forked from Minki/linux
NFS Client Updates for Linux 5.17
- New Features: - Basic handling for case insensitive filesystems - Initial support for fs_locations and server trunking - Bugfixes and Cleanups: - Cleanups to how the "struct cred *" is handled for the nfs_access_entry - Ensure the server has an up to date ctimes before hardlinking or renaming - Update 'blocks used' after writeback, fallocate, and clone - nfs_atomic_open() fixes - Improvements to sunrpc tracing - Various null check & indenting related cleanups - Some improvements to the sunrpc sysfs code - Use default_groups in kobj_type - Fix some potential races and reference leaks - A few tracepoint cleanups in xprtrdma -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEnZ5MQTpR7cLU7KEp18tUv7ClQOsFAmHodsIACgkQ18tUv7Cl QOt3xQ//c9JPmMJZZoZtaD5UrHg28iyxaJpOUUpwC/jxQhLOETCf+nU1cELYgLq5 4W06NBYEmjDJ/tihUvcGMKLvbCtQR9Zl9HepFKDTLTQpGmRFD4enwSmMNvW/AV+h I7PoN6J1DX/TZ5InOHH9asyoC2MjwrNHMn3bbQVT0qy+i3T76zJiBF79eWTnPR48 kKPnF1I0p4LKGJy+y+y/z2mdCsz7tzFkhssxVhot0nafxXzbUOp1H9aiwxroRiUC ljbBA0TX8FWkGpGFt3y2QK2fMD7ovDpRhLFYiJClmeERXJVH5mXL9O5XfN5AL0xe W/QqT5lbWfeHLkpm2j87yTyaHASC7hGKsAyPD0zWLDcNZws61l1Sy4BHymSE5ZVh zt7sJjBnOWAtntyUGBg78G2vhBsd63GzrtcqAOlrngwA5ohJ8f32qvBQGyw4MQu9 75CjRcO8K8mnf9BJ6I1vYPycjkUh9RSFfNdnUEAI9ZwiTEC/hfEvH/omvEtZsNol jBgv2SItTkdMZlEppEL4gxuaYT2wiZf2C6Gco215iPAqLC6dudoroN6yoLk/LRd0 OWZLl5XTr3j6m5QDm22k5CG080vl6XiAxmAFaFSLza6Q34Jmuluc0gLAZZxvqXk9 Ay7dQt9PQQk6mXD5Hreb0E5N9zcm2LkfvWpyGJ7mTV7sSHjA2DU= =wcVT -----END PGP SIGNATURE----- Merge tag 'nfs-for-5.17-1' of git://git.linux-nfs.org/projects/anna/linux-nfs Pull NFS client updates from Anna Schumaker: "New Features: - Basic handling for case insensitive filesystems - Initial support for fs_locations and server trunking Bugfixes and Cleanups: - Cleanups to how the "struct cred *" is handled for the nfs_access_entry - Ensure the server has an up to date ctimes before hardlinking or renaming - Update 'blocks used' after writeback, fallocate, and clone - nfs_atomic_open() fixes - Improvements to sunrpc tracing - Various null check & indenting related cleanups - Some improvements to the sunrpc sysfs code: - Use default_groups in kobj_type - Fix some potential races and reference leaks - A few tracepoint cleanups in xprtrdma" [ This should have gone in during the merge window, but didn't. The original pull request - sent during the merge window - had gotten marked as spam and discarded due missing DKIM headers in the email from Anna. - Linus ] * tag 'nfs-for-5.17-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (35 commits) SUNRPC: Don't dereference xprt->snd_task if it's a cookie xprtrdma: Remove definitions of RPCDBG_FACILITY xprtrdma: Remove final dprintk call sites from xprtrdma sunrpc: Fix potential race conditions in rpc_sysfs_xprt_state_change() net/sunrpc: fix reference count leaks in rpc_sysfs_xprt_state_change NFSv4.1 test and add 4.1 trunking transport SUNRPC allow for unspecified transport time in rpc_clnt_add_xprt NFSv4 handle port presence in fs_location server string NFSv4 expose nfs_parse_server_name function NFSv4.1 query for fs_location attr on a new file system NFSv4 store server support for fs_location attribute NFSv4 remove zero number of fs_locations entries error check NFSv4: nfs_atomic_open() can race when looking up a non-regular file NFSv4: Handle case where the lookup of a directory fails NFSv42: Fallocate and clone should also request 'blocks used' NFSv4: Allow writebacks to request 'blocks used' SUNRPC: use default_groups in kobj_type NFS: use default_groups in kobj_type NFS: Fix the verifier for case sensitive filesystem in nfs_atomic_open() NFS: Add a helper to remove case-insensitive aliases ...
This commit is contained in:
commit
0280e3c58f
@ -170,7 +170,7 @@ struct cb_devicenotifyitem {
|
||||
};
|
||||
|
||||
struct cb_devicenotifyargs {
|
||||
int ndevs;
|
||||
uint32_t ndevs;
|
||||
struct cb_devicenotifyitem *devs;
|
||||
};
|
||||
|
||||
|
@ -358,7 +358,7 @@ __be32 nfs4_callback_devicenotify(void *argp, void *resp,
|
||||
struct cb_process_state *cps)
|
||||
{
|
||||
struct cb_devicenotifyargs *args = argp;
|
||||
int i;
|
||||
uint32_t i;
|
||||
__be32 res = 0;
|
||||
struct nfs_client *clp = cps->clp;
|
||||
struct nfs_server *server = NULL;
|
||||
|
@ -258,11 +258,9 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
|
||||
void *argp)
|
||||
{
|
||||
struct cb_devicenotifyargs *args = argp;
|
||||
uint32_t tmp, n, i;
|
||||
__be32 *p;
|
||||
__be32 status = 0;
|
||||
u32 tmp;
|
||||
int n, i;
|
||||
args->ndevs = 0;
|
||||
|
||||
/* Num of device notifications */
|
||||
p = xdr_inline_decode(xdr, sizeof(uint32_t));
|
||||
@ -271,7 +269,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
|
||||
goto out;
|
||||
}
|
||||
n = ntohl(*p++);
|
||||
if (n <= 0)
|
||||
if (n == 0)
|
||||
goto out;
|
||||
if (n > ULONG_MAX / sizeof(*args->devs)) {
|
||||
status = htonl(NFS4ERR_BADXDR);
|
||||
@ -330,19 +328,21 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
|
||||
dev->cbd_immediate = 0;
|
||||
}
|
||||
|
||||
args->ndevs++;
|
||||
|
||||
dprintk("%s: type %d layout 0x%x immediate %d\n",
|
||||
__func__, dev->cbd_notify_type, dev->cbd_layout_type,
|
||||
dev->cbd_immediate);
|
||||
}
|
||||
args->ndevs = n;
|
||||
dprintk("%s: ndevs %d\n", __func__, args->ndevs);
|
||||
return 0;
|
||||
err:
|
||||
kfree(args->devs);
|
||||
out:
|
||||
args->devs = NULL;
|
||||
args->ndevs = 0;
|
||||
dprintk("%s: status %d ndevs %d\n",
|
||||
__func__, ntohl(status), args->ndevs);
|
||||
return status;
|
||||
err:
|
||||
kfree(args->devs);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static __be32 decode_sessionid(struct xdr_stream *xdr,
|
||||
|
@ -856,6 +856,13 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
|
||||
server->namelen = pathinfo.max_namelen;
|
||||
}
|
||||
|
||||
if (clp->rpc_ops->discover_trunking != NULL &&
|
||||
(server->caps & NFS_CAP_FS_LOCATIONS)) {
|
||||
error = clp->rpc_ops->discover_trunking(server, mntfh);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
146
fs/nfs/dir.c
146
fs/nfs/dir.c
@ -1325,6 +1325,14 @@ void nfs_clear_verifier_delegated(struct inode *inode)
|
||||
EXPORT_SYMBOL_GPL(nfs_clear_verifier_delegated);
|
||||
#endif /* IS_ENABLED(CONFIG_NFS_V4) */
|
||||
|
||||
static int nfs_dentry_verify_change(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE) &&
|
||||
d_really_is_negative(dentry))
|
||||
return dentry->d_time == inode_peek_iversion_raw(dir);
|
||||
return nfs_verify_change_attribute(dir, dentry->d_time);
|
||||
}
|
||||
|
||||
/*
|
||||
* A check for whether or not the parent directory has changed.
|
||||
* In the case it has, we assume that the dentries are untrustworthy
|
||||
@ -1338,7 +1346,7 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry,
|
||||
return 1;
|
||||
if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
|
||||
return 0;
|
||||
if (!nfs_verify_change_attribute(dir, dentry->d_time))
|
||||
if (!nfs_dentry_verify_change(dir, dentry))
|
||||
return 0;
|
||||
/* Revalidate nfsi->cache_change_attribute before we declare a match */
|
||||
if (nfs_mapping_need_revalidate_inode(dir)) {
|
||||
@ -1347,7 +1355,7 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry,
|
||||
if (__nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
|
||||
return 0;
|
||||
}
|
||||
if (!nfs_verify_change_attribute(dir, dentry->d_time))
|
||||
if (!nfs_dentry_verify_change(dir, dentry))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -1437,6 +1445,9 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
|
||||
return 0;
|
||||
if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG)
|
||||
return 1;
|
||||
/* Case insensitive server? Revalidate negative dentries */
|
||||
if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE))
|
||||
return 1;
|
||||
return !nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU);
|
||||
}
|
||||
|
||||
@ -1537,7 +1548,7 @@ out:
|
||||
* If the lookup failed despite the dentry change attribute being
|
||||
* a match, then we should revalidate the directory cache.
|
||||
*/
|
||||
if (!ret && nfs_verify_change_attribute(dir, dentry->d_time))
|
||||
if (!ret && nfs_dentry_verify_change(dir, dentry))
|
||||
nfs_mark_dir_for_revalidate(dir);
|
||||
return nfs_lookup_revalidate_done(dir, dentry, inode, ret);
|
||||
}
|
||||
@ -1776,8 +1787,11 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
|
||||
dir_verifier = nfs_save_change_attribute(dir);
|
||||
trace_nfs_lookup_enter(dir, dentry, flags);
|
||||
error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr);
|
||||
if (error == -ENOENT)
|
||||
if (error == -ENOENT) {
|
||||
if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE))
|
||||
dir_verifier = inode_peek_iversion_raw(dir);
|
||||
goto no_entry;
|
||||
}
|
||||
if (error < 0) {
|
||||
res = ERR_PTR(error);
|
||||
goto out;
|
||||
@ -1806,6 +1820,14 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_lookup);
|
||||
|
||||
void nfs_d_prune_case_insensitive_aliases(struct inode *inode)
|
||||
{
|
||||
/* Case insensitive server? Revalidate dentries */
|
||||
if (inode && nfs_server_capable(inode, NFS_CAP_CASE_INSENSITIVE))
|
||||
d_prune_aliases(inode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_d_prune_case_insensitive_aliases);
|
||||
|
||||
#if IS_ENABLED(CONFIG_NFS_V4)
|
||||
static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
|
||||
|
||||
@ -1867,6 +1889,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
struct iattr attr = { .ia_valid = ATTR_OPEN };
|
||||
struct inode *inode;
|
||||
unsigned int lookup_flags = 0;
|
||||
unsigned long dir_verifier;
|
||||
bool switched = false;
|
||||
int created = 0;
|
||||
int err;
|
||||
@ -1940,7 +1963,11 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
switch (err) {
|
||||
case -ENOENT:
|
||||
d_splice_alias(NULL, dentry);
|
||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||
if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE))
|
||||
dir_verifier = inode_peek_iversion_raw(dir);
|
||||
else
|
||||
dir_verifier = nfs_save_change_attribute(dir);
|
||||
nfs_set_verifier(dentry, dir_verifier);
|
||||
break;
|
||||
case -EISDIR:
|
||||
case -ENOTDIR:
|
||||
@ -1968,6 +1995,24 @@ out:
|
||||
|
||||
no_open:
|
||||
res = nfs_lookup(dir, dentry, lookup_flags);
|
||||
if (!res) {
|
||||
inode = d_inode(dentry);
|
||||
if ((lookup_flags & LOOKUP_DIRECTORY) && inode &&
|
||||
!S_ISDIR(inode->i_mode))
|
||||
res = ERR_PTR(-ENOTDIR);
|
||||
else if (inode && S_ISREG(inode->i_mode))
|
||||
res = ERR_PTR(-EOPENSTALE);
|
||||
} else if (!IS_ERR(res)) {
|
||||
inode = d_inode(res);
|
||||
if ((lookup_flags & LOOKUP_DIRECTORY) && inode &&
|
||||
!S_ISDIR(inode->i_mode)) {
|
||||
dput(res);
|
||||
res = ERR_PTR(-ENOTDIR);
|
||||
} else if (inode && S_ISREG(inode->i_mode)) {
|
||||
dput(res);
|
||||
res = ERR_PTR(-EOPENSTALE);
|
||||
}
|
||||
}
|
||||
if (switched) {
|
||||
d_lookup_done(dentry);
|
||||
if (!res)
|
||||
@ -2186,8 +2231,10 @@ static void nfs_dentry_remove_handle_error(struct inode *dir,
|
||||
switch (error) {
|
||||
case -ENOENT:
|
||||
d_delete(dentry);
|
||||
fallthrough;
|
||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||
break;
|
||||
case 0:
|
||||
nfs_d_prune_case_insensitive_aliases(d_inode(dentry));
|
||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||
}
|
||||
}
|
||||
@ -2380,6 +2427,8 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
||||
|
||||
trace_nfs_link_enter(inode, dir, dentry);
|
||||
d_drop(dentry);
|
||||
if (S_ISREG(inode->i_mode))
|
||||
nfs_sync_inode(inode);
|
||||
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
|
||||
if (error == 0) {
|
||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||
@ -2469,6 +2518,8 @@ int nfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISREG(old_inode->i_mode))
|
||||
nfs_sync_inode(old_inode);
|
||||
task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
|
||||
if (IS_ERR(task)) {
|
||||
error = PTR_ERR(task);
|
||||
@ -2529,7 +2580,7 @@ MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache lengt
|
||||
|
||||
static void nfs_access_free_entry(struct nfs_access_entry *entry)
|
||||
{
|
||||
put_cred(entry->cred);
|
||||
put_group_info(entry->group_info);
|
||||
kfree_rcu(entry, rcu_head);
|
||||
smp_mb__before_atomic();
|
||||
atomic_long_dec(&nfs_access_nr_entries);
|
||||
@ -2655,6 +2706,43 @@ void nfs_access_zap_cache(struct inode *inode)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
|
||||
|
||||
static int access_cmp(const struct cred *a, const struct nfs_access_entry *b)
|
||||
{
|
||||
struct group_info *ga, *gb;
|
||||
int g;
|
||||
|
||||
if (uid_lt(a->fsuid, b->fsuid))
|
||||
return -1;
|
||||
if (uid_gt(a->fsuid, b->fsuid))
|
||||
return 1;
|
||||
|
||||
if (gid_lt(a->fsgid, b->fsgid))
|
||||
return -1;
|
||||
if (gid_gt(a->fsgid, b->fsgid))
|
||||
return 1;
|
||||
|
||||
ga = a->group_info;
|
||||
gb = b->group_info;
|
||||
if (ga == gb)
|
||||
return 0;
|
||||
if (ga == NULL)
|
||||
return -1;
|
||||
if (gb == NULL)
|
||||
return 1;
|
||||
if (ga->ngroups < gb->ngroups)
|
||||
return -1;
|
||||
if (ga->ngroups > gb->ngroups)
|
||||
return 1;
|
||||
|
||||
for (g = 0; g < ga->ngroups; g++) {
|
||||
if (gid_lt(ga->gid[g], gb->gid[g]))
|
||||
return -1;
|
||||
if (gid_gt(ga->gid[g], gb->gid[g]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, const struct cred *cred)
|
||||
{
|
||||
struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
|
||||
@ -2662,7 +2750,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co
|
||||
while (n != NULL) {
|
||||
struct nfs_access_entry *entry =
|
||||
rb_entry(n, struct nfs_access_entry, rb_node);
|
||||
int cmp = cred_fscmp(cred, entry->cred);
|
||||
int cmp = access_cmp(cred, entry);
|
||||
|
||||
if (cmp < 0)
|
||||
n = n->rb_left;
|
||||
@ -2674,7 +2762,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
|
||||
static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, u32 *mask, bool may_block)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct nfs_access_entry *cache;
|
||||
@ -2704,8 +2792,7 @@ static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *
|
||||
spin_lock(&inode->i_lock);
|
||||
retry = false;
|
||||
}
|
||||
res->cred = cache->cred;
|
||||
res->mask = cache->mask;
|
||||
*mask = cache->mask;
|
||||
list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru);
|
||||
err = 0;
|
||||
out:
|
||||
@ -2717,7 +2804,7 @@ out_zap:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res)
|
||||
static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, u32 *mask)
|
||||
{
|
||||
/* Only check the most recently returned cache entry,
|
||||
* but do it without locking.
|
||||
@ -2733,35 +2820,36 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
|
||||
lh = rcu_dereference(list_tail_rcu(&nfsi->access_cache_entry_lru));
|
||||
cache = list_entry(lh, struct nfs_access_entry, lru);
|
||||
if (lh == &nfsi->access_cache_entry_lru ||
|
||||
cred_fscmp(cred, cache->cred) != 0)
|
||||
access_cmp(cred, cache) != 0)
|
||||
cache = NULL;
|
||||
if (cache == NULL)
|
||||
goto out;
|
||||
if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
|
||||
goto out;
|
||||
res->cred = cache->cred;
|
||||
res->mask = cache->mask;
|
||||
*mask = cache->mask;
|
||||
err = 0;
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct
|
||||
nfs_access_entry *res, bool may_block)
|
||||
int nfs_access_get_cached(struct inode *inode, const struct cred *cred,
|
||||
u32 *mask, bool may_block)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = nfs_access_get_cached_rcu(inode, cred, res);
|
||||
status = nfs_access_get_cached_rcu(inode, cred, mask);
|
||||
if (status != 0)
|
||||
status = nfs_access_get_cached_locked(inode, cred, res,
|
||||
status = nfs_access_get_cached_locked(inode, cred, mask,
|
||||
may_block);
|
||||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfs_access_get_cached);
|
||||
|
||||
static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set)
|
||||
static void nfs_access_add_rbtree(struct inode *inode,
|
||||
struct nfs_access_entry *set,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
struct rb_root *root_node = &nfsi->access_cache;
|
||||
@ -2774,7 +2862,7 @@ static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *
|
||||
while (*p != NULL) {
|
||||
parent = *p;
|
||||
entry = rb_entry(parent, struct nfs_access_entry, rb_node);
|
||||
cmp = cred_fscmp(set->cred, entry->cred);
|
||||
cmp = access_cmp(cred, entry);
|
||||
|
||||
if (cmp < 0)
|
||||
p = &parent->rb_left;
|
||||
@ -2796,13 +2884,16 @@ found:
|
||||
nfs_access_free_entry(entry);
|
||||
}
|
||||
|
||||
void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
|
||||
void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
|
||||
if (cache == NULL)
|
||||
return;
|
||||
RB_CLEAR_NODE(&cache->rb_node);
|
||||
cache->cred = get_cred(set->cred);
|
||||
cache->fsuid = cred->fsuid;
|
||||
cache->fsgid = cred->fsgid;
|
||||
cache->group_info = get_group_info(cred->group_info);
|
||||
cache->mask = set->mask;
|
||||
|
||||
/* The above field assignments must be visible
|
||||
@ -2810,7 +2901,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
|
||||
* use rcu_assign_pointer, so just force the memory barrier.
|
||||
*/
|
||||
smp_wmb();
|
||||
nfs_access_add_rbtree(inode, cache);
|
||||
nfs_access_add_rbtree(inode, cache, cred);
|
||||
|
||||
/* Update accounting */
|
||||
smp_mb__before_atomic();
|
||||
@ -2875,7 +2966,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
|
||||
|
||||
trace_nfs_access_enter(inode);
|
||||
|
||||
status = nfs_access_get_cached(inode, cred, &cache, may_block);
|
||||
status = nfs_access_get_cached(inode, cred, &cache.mask, may_block);
|
||||
if (status == 0)
|
||||
goto out_cached;
|
||||
|
||||
@ -2895,8 +2986,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
|
||||
cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP;
|
||||
else
|
||||
cache.mask |= NFS_ACCESS_EXECUTE;
|
||||
cache.cred = cred;
|
||||
status = NFS_PROTO(inode)->access(inode, &cache);
|
||||
status = NFS_PROTO(inode)->access(inode, &cache, cred);
|
||||
if (status != 0) {
|
||||
if (status == -ESTALE) {
|
||||
if (!S_ISDIR(inode->i_mode))
|
||||
@ -2906,7 +2996,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
nfs_access_add_cache(inode, &cache);
|
||||
nfs_access_add_cache(inode, &cache, cred);
|
||||
out_cached:
|
||||
cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
|
||||
if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
|
||||
|
@ -51,7 +51,7 @@ struct nfs4_file_layout_dsaddr {
|
||||
u32 stripe_count;
|
||||
u8 *stripe_indices;
|
||||
u32 ds_num;
|
||||
struct nfs4_pnfs_ds *ds_list[1];
|
||||
struct nfs4_pnfs_ds *ds_list[];
|
||||
};
|
||||
|
||||
struct nfs4_filelayout_segment {
|
||||
|
@ -136,9 +136,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
|
||||
goto out_err_free_stripe_indices;
|
||||
}
|
||||
|
||||
dsaddr = kzalloc(sizeof(*dsaddr) +
|
||||
(sizeof(struct nfs4_pnfs_ds *) * (num - 1)),
|
||||
gfp_flags);
|
||||
dsaddr = kzalloc(struct_size(dsaddr, ds_list, num), gfp_flags);
|
||||
if (!dsaddr)
|
||||
goto out_err_free_stripe_indices;
|
||||
|
||||
|
@ -373,6 +373,7 @@ extern unsigned long nfs_access_cache_count(struct shrinker *shrink,
|
||||
extern unsigned long nfs_access_cache_scan(struct shrinker *shrink,
|
||||
struct shrink_control *sc);
|
||||
struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int);
|
||||
void nfs_d_prune_case_insensitive_aliases(struct inode *inode);
|
||||
int nfs_create(struct user_namespace *, struct inode *, struct dentry *,
|
||||
umode_t, bool);
|
||||
int nfs_mkdir(struct user_namespace *, struct inode *, struct dentry *,
|
||||
|
@ -220,7 +220,8 @@ static int nfs3_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
|
||||
task_flags);
|
||||
}
|
||||
|
||||
static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
||||
static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs3_accessargs arg = {
|
||||
.fh = NFS_FH(inode),
|
||||
@ -231,7 +232,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
||||
.rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS],
|
||||
.rpc_argp = &arg,
|
||||
.rpc_resp = &res,
|
||||
.rpc_cred = entry->cred,
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
int status = -ENOMEM;
|
||||
|
||||
|
@ -46,7 +46,7 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
|
||||
{
|
||||
struct inode *inode = file_inode(filep);
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
u32 bitmask[3];
|
||||
u32 bitmask[NFS_BITMASK_SZ];
|
||||
struct nfs42_falloc_args args = {
|
||||
.falloc_fh = NFS_FH(inode),
|
||||
.falloc_offset = offset,
|
||||
@ -69,9 +69,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
|
||||
return status;
|
||||
}
|
||||
|
||||
memcpy(bitmask, server->cache_consistency_bitmask, sizeof(bitmask));
|
||||
if (server->attr_bitmask[1] & FATTR4_WORD1_SPACE_USED)
|
||||
bitmask[1] |= FATTR4_WORD1_SPACE_USED;
|
||||
nfs4_bitmask_set(bitmask, server->cache_consistency_bitmask, inode,
|
||||
NFS_INO_INVALID_BLOCKS);
|
||||
|
||||
res.falloc_fattr = nfs_alloc_fattr();
|
||||
if (!res.falloc_fattr)
|
||||
@ -1044,13 +1043,14 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
|
||||
struct inode *src_inode = file_inode(src_f);
|
||||
struct inode *dst_inode = file_inode(dst_f);
|
||||
struct nfs_server *server = NFS_SERVER(dst_inode);
|
||||
__u32 dst_bitmask[NFS_BITMASK_SZ];
|
||||
struct nfs42_clone_args args = {
|
||||
.src_fh = NFS_FH(src_inode),
|
||||
.dst_fh = NFS_FH(dst_inode),
|
||||
.src_offset = src_offset,
|
||||
.dst_offset = dst_offset,
|
||||
.count = count,
|
||||
.dst_bitmask = server->cache_consistency_bitmask,
|
||||
.dst_bitmask = dst_bitmask,
|
||||
};
|
||||
struct nfs42_clone_res res = {
|
||||
.server = server,
|
||||
@ -1079,6 +1079,9 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
|
||||
if (!res.dst_fattr)
|
||||
return -ENOMEM;
|
||||
|
||||
nfs4_bitmask_set(dst_bitmask, server->cache_consistency_bitmask,
|
||||
dst_inode, NFS_INO_INVALID_BLOCKS);
|
||||
|
||||
status = nfs4_call_sync(server->client, server, msg,
|
||||
&args.seq_args, &res.seq_res, 0);
|
||||
trace_nfs4_clone(src_inode, dst_inode, &args, status);
|
||||
|
@ -260,8 +260,8 @@ struct nfs4_state_maintenance_ops {
|
||||
};
|
||||
|
||||
struct nfs4_mig_recovery_ops {
|
||||
int (*get_locations)(struct inode *, struct nfs4_fs_locations *,
|
||||
struct page *, const struct cred *);
|
||||
int (*get_locations)(struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs4_fs_locations *, struct page *, const struct cred *);
|
||||
int (*fsid_present)(struct inode *, const struct cred *);
|
||||
};
|
||||
|
||||
@ -280,7 +280,8 @@ struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *,
|
||||
int nfs4_submount(struct fs_context *, struct nfs_server *);
|
||||
int nfs4_replace_transport(struct nfs_server *server,
|
||||
const struct nfs4_fs_locations *locations);
|
||||
|
||||
size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa,
|
||||
size_t salen, struct net *net, int port);
|
||||
/* nfs4proc.c */
|
||||
extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
|
||||
extern int nfs4_async_handle_error(struct rpc_task *task,
|
||||
@ -302,8 +303,9 @@ extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
|
||||
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
|
||||
extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
|
||||
struct nfs4_fs_locations *, struct page *);
|
||||
extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
|
||||
struct page *page, const struct cred *);
|
||||
extern int nfs4_proc_get_locations(struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs4_fs_locations *,
|
||||
struct page *page, const struct cred *);
|
||||
extern int nfs4_proc_fsid_present(struct inode *, const struct cred *);
|
||||
extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *,
|
||||
struct dentry *,
|
||||
@ -315,6 +317,8 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
|
||||
const struct nfs_open_context *ctx,
|
||||
const struct nfs_lock_context *l_ctx,
|
||||
fmode_t fmode);
|
||||
extern void nfs4_bitmask_set(__u32 bitmask[], const __u32 src[],
|
||||
struct inode *inode, unsigned long cache_validity);
|
||||
extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
struct nfs_fattr *fattr, struct inode *inode);
|
||||
extern int update_open_stateid(struct nfs4_state *state,
|
||||
|
@ -1343,8 +1343,11 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
|
||||
}
|
||||
nfs_put_client(clp);
|
||||
|
||||
if (server->nfs_client->cl_hostname == NULL)
|
||||
if (server->nfs_client->cl_hostname == NULL) {
|
||||
server->nfs_client->cl_hostname = kstrdup(hostname, GFP_KERNEL);
|
||||
if (server->nfs_client->cl_hostname == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
nfs_server_insert_lists(server);
|
||||
|
||||
return nfs_probe_server(server, NFS_FH(d_inode(server->super->s_root)));
|
||||
|
@ -164,16 +164,21 @@ static int nfs4_validate_fspath(struct dentry *dentry,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t nfs_parse_server_name(char *string, size_t len,
|
||||
struct sockaddr *sa, size_t salen, struct net *net)
|
||||
size_t nfs_parse_server_name(char *string, size_t len, struct sockaddr *sa,
|
||||
size_t salen, struct net *net, int port)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
ret = rpc_pton(net, string, len, sa, salen);
|
||||
if (ret == 0) {
|
||||
ret = nfs_dns_resolve_name(net, string, len, sa, salen);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
ret = rpc_uaddr2sockaddr(net, string, len, sa, salen);
|
||||
if (ret == 0) {
|
||||
ret = nfs_dns_resolve_name(net, string, len, sa, salen);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
}
|
||||
} else if (port) {
|
||||
rpc_set_port(sa, port);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -328,7 +333,7 @@ static int try_location(struct fs_context *fc,
|
||||
nfs_parse_server_name(buf->data, buf->len,
|
||||
&ctx->nfs_server.address,
|
||||
sizeof(ctx->nfs_server._address),
|
||||
fc->net_ns);
|
||||
fc->net_ns, 0);
|
||||
if (ctx->nfs_server.addrlen == 0)
|
||||
continue;
|
||||
|
||||
@ -496,7 +501,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server,
|
||||
continue;
|
||||
|
||||
salen = nfs_parse_server_name(buf->data, buf->len,
|
||||
sap, addr_bufsize, net);
|
||||
sap, addr_bufsize, net, 0);
|
||||
if (salen == 0)
|
||||
continue;
|
||||
rpc_set_port(sap, NFS_PORT);
|
||||
|
@ -108,10 +108,6 @@ static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
|
||||
static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *,
|
||||
const struct cred *, bool);
|
||||
#endif
|
||||
static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ],
|
||||
const __u32 *src, struct inode *inode,
|
||||
struct nfs_server *server,
|
||||
struct nfs4_label *label);
|
||||
|
||||
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
||||
static inline struct nfs4_label *
|
||||
@ -2653,9 +2649,8 @@ static int nfs4_opendata_access(const struct cred *cred,
|
||||
} else if ((fmode & FMODE_READ) && !opendata->file_created)
|
||||
mask = NFS4_ACCESS_READ;
|
||||
|
||||
cache.cred = cred;
|
||||
nfs_access_set_mask(&cache, opendata->o_res.access_result);
|
||||
nfs_access_add_cache(state->inode, &cache);
|
||||
nfs_access_add_cache(state->inode, &cache, cred);
|
||||
|
||||
flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP;
|
||||
if ((mask & ~cache.mask & flags) == 0)
|
||||
@ -3670,7 +3665,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
|
||||
if (!nfs4_have_delegation(inode, FMODE_READ)) {
|
||||
nfs4_bitmask_set(calldata->arg.bitmask_store,
|
||||
server->cache_consistency_bitmask,
|
||||
inode, server, NULL);
|
||||
inode, 0);
|
||||
calldata->arg.bitmask = calldata->arg.bitmask_store;
|
||||
} else
|
||||
calldata->arg.bitmask = NULL;
|
||||
@ -3841,7 +3836,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
||||
FATTR4_WORD0_FH_EXPIRE_TYPE |
|
||||
FATTR4_WORD0_LINK_SUPPORT |
|
||||
FATTR4_WORD0_SYMLINK_SUPPORT |
|
||||
FATTR4_WORD0_ACLSUPPORT;
|
||||
FATTR4_WORD0_ACLSUPPORT |
|
||||
FATTR4_WORD0_CASE_INSENSITIVE |
|
||||
FATTR4_WORD0_CASE_PRESERVING;
|
||||
if (minorversion)
|
||||
bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT;
|
||||
|
||||
@ -3870,10 +3867,16 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
||||
server->caps |= NFS_CAP_HARDLINKS;
|
||||
if (res.has_symlinks != 0)
|
||||
server->caps |= NFS_CAP_SYMLINKS;
|
||||
if (res.case_insensitive)
|
||||
server->caps |= NFS_CAP_CASE_INSENSITIVE;
|
||||
if (res.case_preserving)
|
||||
server->caps |= NFS_CAP_CASE_PRESERVING;
|
||||
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
||||
if (res.attr_bitmask[2] & FATTR4_WORD2_SECURITY_LABEL)
|
||||
server->caps |= NFS_CAP_SECURITY_LABEL;
|
||||
#endif
|
||||
if (res.attr_bitmask[0] & FATTR4_WORD0_FS_LOCATIONS)
|
||||
server->caps |= NFS_CAP_FS_LOCATIONS;
|
||||
if (!(res.attr_bitmask[0] & FATTR4_WORD0_FILEID))
|
||||
server->fattr_valid &= ~NFS_ATTR_FATTR_FILEID;
|
||||
if (!(res.attr_bitmask[1] & FATTR4_WORD1_MODE))
|
||||
@ -3932,6 +3935,114 @@ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void test_fs_location_for_trunking(struct nfs4_fs_location *location,
|
||||
struct nfs_client *clp,
|
||||
struct nfs_server *server)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < location->nservers; i++) {
|
||||
struct nfs4_string *srv_loc = &location->servers[i];
|
||||
struct sockaddr addr;
|
||||
size_t addrlen;
|
||||
struct xprt_create xprt_args = {
|
||||
.ident = 0,
|
||||
.net = clp->cl_net,
|
||||
};
|
||||
struct nfs4_add_xprt_data xprtdata = {
|
||||
.clp = clp,
|
||||
};
|
||||
struct rpc_add_xprt_test rpcdata = {
|
||||
.add_xprt_test = clp->cl_mvops->session_trunk,
|
||||
.data = &xprtdata,
|
||||
};
|
||||
char *servername = NULL;
|
||||
|
||||
if (!srv_loc->len)
|
||||
continue;
|
||||
|
||||
addrlen = nfs_parse_server_name(srv_loc->data, srv_loc->len,
|
||||
&addr, sizeof(addr),
|
||||
clp->cl_net, server->port);
|
||||
if (!addrlen)
|
||||
return;
|
||||
xprt_args.dstaddr = &addr;
|
||||
xprt_args.addrlen = addrlen;
|
||||
servername = kmalloc(srv_loc->len + 1, GFP_KERNEL);
|
||||
if (!servername)
|
||||
return;
|
||||
memcpy(servername, srv_loc->data, srv_loc->len);
|
||||
servername[srv_loc->len] = '\0';
|
||||
xprt_args.servername = servername;
|
||||
|
||||
xprtdata.cred = nfs4_get_clid_cred(clp);
|
||||
rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
|
||||
rpc_clnt_setup_test_and_add_xprt,
|
||||
&rpcdata);
|
||||
if (xprtdata.cred)
|
||||
put_cred(xprtdata.cred);
|
||||
kfree(servername);
|
||||
}
|
||||
}
|
||||
|
||||
static int _nfs4_discover_trunking(struct nfs_server *server,
|
||||
struct nfs_fh *fhandle)
|
||||
{
|
||||
struct nfs4_fs_locations *locations = NULL;
|
||||
struct page *page;
|
||||
const struct cred *cred;
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
const struct nfs4_state_maintenance_ops *ops =
|
||||
clp->cl_mvops->state_renewal_ops;
|
||||
int status = -ENOMEM, i;
|
||||
|
||||
cred = ops->get_state_renewal_cred(clp);
|
||||
if (cred == NULL) {
|
||||
cred = nfs4_get_clid_cred(clp);
|
||||
if (cred == NULL)
|
||||
return -ENOKEY;
|
||||
}
|
||||
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
|
||||
if (page == NULL || locations == NULL)
|
||||
goto out;
|
||||
|
||||
status = nfs4_proc_get_locations(server, fhandle, locations, page,
|
||||
cred);
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < locations->nlocations; i++)
|
||||
test_fs_location_for_trunking(&locations->locations[i], clp,
|
||||
server);
|
||||
out:
|
||||
if (page)
|
||||
__free_page(page);
|
||||
kfree(locations);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_discover_trunking(struct nfs_server *server,
|
||||
struct nfs_fh *fhandle)
|
||||
{
|
||||
struct nfs4_exception exception = {
|
||||
.interruptible = true,
|
||||
};
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
int err = 0;
|
||||
|
||||
if (!nfs4_has_session(clp))
|
||||
goto out;
|
||||
do {
|
||||
err = nfs4_handle_exception(server,
|
||||
_nfs4_discover_trunking(server, fhandle),
|
||||
&exception);
|
||||
} while (exception.retry);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
struct nfs_fsinfo *info)
|
||||
{
|
||||
@ -4441,7 +4552,8 @@ static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
||||
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs4_accessargs args = {
|
||||
@ -4455,7 +4567,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
|
||||
.rpc_argp = &args,
|
||||
.rpc_resp = &res,
|
||||
.rpc_cred = entry->cred,
|
||||
.rpc_cred = cred,
|
||||
};
|
||||
int status = 0;
|
||||
|
||||
@ -4475,14 +4587,15 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
|
||||
return status;
|
||||
}
|
||||
|
||||
static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
|
||||
static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct nfs4_exception exception = {
|
||||
.interruptible = true,
|
||||
};
|
||||
int err;
|
||||
do {
|
||||
err = _nfs4_proc_access(inode, entry);
|
||||
err = _nfs4_proc_access(inode, entry, cred);
|
||||
trace_nfs4_access(inode, err);
|
||||
err = nfs4_handle_exception(NFS_SERVER(inode), err,
|
||||
&exception);
|
||||
@ -4663,8 +4776,10 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg,
|
||||
|
||||
nfs_fattr_init(res->dir_attr);
|
||||
|
||||
if (inode)
|
||||
if (inode) {
|
||||
nfs4_inode_return_delegation(inode);
|
||||
nfs_d_prune_case_insensitive_aliases(inode);
|
||||
}
|
||||
}
|
||||
|
||||
static void nfs4_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
|
||||
@ -4730,6 +4845,7 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
|
||||
return 0;
|
||||
|
||||
if (task->tk_status == 0) {
|
||||
nfs_d_prune_case_insensitive_aliases(d_inode(data->old_dentry));
|
||||
if (new_dir != old_dir) {
|
||||
/* Note: If we moved a directory, nlink will change */
|
||||
nfs4_update_changeattr(old_dir, &res->old_cinfo,
|
||||
@ -5422,14 +5538,14 @@ bool nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr)
|
||||
return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0;
|
||||
}
|
||||
|
||||
static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src,
|
||||
struct inode *inode, struct nfs_server *server,
|
||||
struct nfs4_label *label)
|
||||
void nfs4_bitmask_set(__u32 bitmask[], const __u32 src[],
|
||||
struct inode *inode, unsigned long cache_validity)
|
||||
{
|
||||
unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
unsigned int i;
|
||||
|
||||
memcpy(bitmask, src, sizeof(*bitmask) * NFS4_BITMASK_SZ);
|
||||
cache_validity |= READ_ONCE(NFS_I(inode)->cache_validity);
|
||||
|
||||
if (cache_validity & NFS_INO_INVALID_CHANGE)
|
||||
bitmask[0] |= FATTR4_WORD0_CHANGE;
|
||||
@ -5441,8 +5557,6 @@ static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src,
|
||||
bitmask[1] |= FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP;
|
||||
if (cache_validity & NFS_INO_INVALID_NLINK)
|
||||
bitmask[1] |= FATTR4_WORD1_NUMLINKS;
|
||||
if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL)
|
||||
bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
|
||||
if (cache_validity & NFS_INO_INVALID_CTIME)
|
||||
bitmask[1] |= FATTR4_WORD1_TIME_METADATA;
|
||||
if (cache_validity & NFS_INO_INVALID_MTIME)
|
||||
@ -5469,7 +5583,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
|
||||
} else {
|
||||
nfs4_bitmask_set(hdr->args.bitmask_store,
|
||||
server->cache_consistency_bitmask,
|
||||
hdr->inode, server, NULL);
|
||||
hdr->inode, NFS_INO_INVALID_BLOCKS);
|
||||
hdr->args.bitmask = hdr->args.bitmask_store;
|
||||
}
|
||||
|
||||
@ -6507,8 +6621,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
|
||||
data->args.fhandle = &data->fh;
|
||||
data->args.stateid = &data->stateid;
|
||||
nfs4_bitmask_set(data->args.bitmask_store,
|
||||
server->cache_consistency_bitmask, inode, server,
|
||||
NULL);
|
||||
server->cache_consistency_bitmask, inode, 0);
|
||||
data->args.bitmask = data->args.bitmask_store;
|
||||
nfs_copy_fh(&data->fh, NFS_FH(inode));
|
||||
nfs4_stateid_copy(&data->stateid, stateid);
|
||||
@ -7611,7 +7724,7 @@ static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler,
|
||||
const char *key, const void *buf,
|
||||
size_t buflen, int flags)
|
||||
{
|
||||
struct nfs_access_entry cache;
|
||||
u32 mask;
|
||||
int ret;
|
||||
|
||||
if (!nfs_server_capable(inode, NFS_CAP_XATTR))
|
||||
@ -7626,8 +7739,8 @@ static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler,
|
||||
* do a cached access check for the XA* flags to possibly avoid
|
||||
* doing an RPC and getting EACCES back.
|
||||
*/
|
||||
if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
|
||||
if (!(cache.mask & NFS_ACCESS_XAWRITE))
|
||||
if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) {
|
||||
if (!(mask & NFS_ACCESS_XAWRITE))
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
@ -7648,14 +7761,14 @@ static int nfs4_xattr_get_nfs4_user(const struct xattr_handler *handler,
|
||||
struct dentry *unused, struct inode *inode,
|
||||
const char *key, void *buf, size_t buflen)
|
||||
{
|
||||
struct nfs_access_entry cache;
|
||||
u32 mask;
|
||||
ssize_t ret;
|
||||
|
||||
if (!nfs_server_capable(inode, NFS_CAP_XATTR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
|
||||
if (!(cache.mask & NFS_ACCESS_XAREAD))
|
||||
if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) {
|
||||
if (!(mask & NFS_ACCESS_XAREAD))
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
@ -7680,13 +7793,13 @@ nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
|
||||
ssize_t ret, size;
|
||||
char *buf;
|
||||
size_t buflen;
|
||||
struct nfs_access_entry cache;
|
||||
u32 mask;
|
||||
|
||||
if (!nfs_server_capable(inode, NFS_CAP_XATTR))
|
||||
return 0;
|
||||
|
||||
if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
|
||||
if (!(cache.mask & NFS_ACCESS_XALIST))
|
||||
if (!nfs_access_get_cached(inode, current_cred(), &mask, true)) {
|
||||
if (!(mask & NFS_ACCESS_XALIST))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7818,18 +7931,18 @@ int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
|
||||
* appended to this compound to identify the client ID which is
|
||||
* performing recovery.
|
||||
*/
|
||||
static int _nfs40_proc_get_locations(struct inode *inode,
|
||||
static int _nfs40_proc_get_locations(struct nfs_server *server,
|
||||
struct nfs_fh *fhandle,
|
||||
struct nfs4_fs_locations *locations,
|
||||
struct page *page, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
u32 bitmask[2] = {
|
||||
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
|
||||
};
|
||||
struct nfs4_fs_locations_arg args = {
|
||||
.clientid = server->nfs_client->cl_clientid,
|
||||
.fh = NFS_FH(inode),
|
||||
.fh = fhandle,
|
||||
.page = page,
|
||||
.bitmask = bitmask,
|
||||
.migration = 1, /* skip LOOKUP */
|
||||
@ -7875,17 +7988,17 @@ static int _nfs40_proc_get_locations(struct inode *inode,
|
||||
* When the client supports GETATTR(fs_locations_info), it can
|
||||
* be plumbed in here.
|
||||
*/
|
||||
static int _nfs41_proc_get_locations(struct inode *inode,
|
||||
static int _nfs41_proc_get_locations(struct nfs_server *server,
|
||||
struct nfs_fh *fhandle,
|
||||
struct nfs4_fs_locations *locations,
|
||||
struct page *page, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct rpc_clnt *clnt = server->client;
|
||||
u32 bitmask[2] = {
|
||||
[0] = FATTR4_WORD0_FSID | FATTR4_WORD0_FS_LOCATIONS,
|
||||
};
|
||||
struct nfs4_fs_locations_arg args = {
|
||||
.fh = NFS_FH(inode),
|
||||
.fh = fhandle,
|
||||
.page = page,
|
||||
.bitmask = bitmask,
|
||||
.migration = 1, /* skip LOOKUP */
|
||||
@ -7934,11 +8047,11 @@ static int _nfs41_proc_get_locations(struct inode *inode,
|
||||
* -NFS4ERR_LEASE_MOVED is returned if the server still has leases
|
||||
* from this client that require migration recovery.
|
||||
*/
|
||||
int nfs4_proc_get_locations(struct inode *inode,
|
||||
int nfs4_proc_get_locations(struct nfs_server *server,
|
||||
struct nfs_fh *fhandle,
|
||||
struct nfs4_fs_locations *locations,
|
||||
struct page *page, const struct cred *cred)
|
||||
{
|
||||
struct nfs_server *server = NFS_SERVER(inode);
|
||||
struct nfs_client *clp = server->nfs_client;
|
||||
const struct nfs4_mig_recovery_ops *ops =
|
||||
clp->cl_mvops->mig_recovery_ops;
|
||||
@ -7951,10 +8064,11 @@ int nfs4_proc_get_locations(struct inode *inode,
|
||||
(unsigned long long)server->fsid.major,
|
||||
(unsigned long long)server->fsid.minor,
|
||||
clp->cl_hostname);
|
||||
nfs_display_fhandle(NFS_FH(inode), __func__);
|
||||
nfs_display_fhandle(fhandle, __func__);
|
||||
|
||||
do {
|
||||
status = ops->get_locations(inode, locations, page, cred);
|
||||
status = ops->get_locations(server, fhandle, locations, page,
|
||||
cred);
|
||||
if (status != -NFS4ERR_DELAY)
|
||||
break;
|
||||
nfs4_handle_exception(server, status, &exception);
|
||||
@ -10423,6 +10537,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
|
||||
.free_client = nfs4_free_client,
|
||||
.create_server = nfs4_create_server,
|
||||
.clone_server = nfs_clone_server,
|
||||
.discover_trunking = nfs4_discover_trunking,
|
||||
};
|
||||
|
||||
static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
|
||||
|
@ -2098,7 +2098,8 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
|
||||
}
|
||||
|
||||
inode = d_inode(server->super->s_root);
|
||||
result = nfs4_proc_get_locations(inode, locations, page, cred);
|
||||
result = nfs4_proc_get_locations(server, NFS_FH(inode), locations,
|
||||
page, cred);
|
||||
if (result) {
|
||||
dprintk("<-- %s: failed to retrieve fs_locations: %d\n",
|
||||
__func__, result);
|
||||
@ -2106,6 +2107,9 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred
|
||||
}
|
||||
|
||||
result = -NFS4ERR_NXIO;
|
||||
if (!locations->nlocations)
|
||||
goto out;
|
||||
|
||||
if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) {
|
||||
dprintk("<-- %s: No fs_locations data, migration skipped\n",
|
||||
__func__);
|
||||
|
@ -3533,6 +3533,42 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_attr_case_insensitive(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
*res = 0;
|
||||
if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_INSENSITIVE - 1U)))
|
||||
return -EIO;
|
||||
if (likely(bitmap[0] & FATTR4_WORD0_CASE_INSENSITIVE)) {
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
if (unlikely(!p))
|
||||
return -EIO;
|
||||
*res = be32_to_cpup(p);
|
||||
bitmap[0] &= ~FATTR4_WORD0_CASE_INSENSITIVE;
|
||||
}
|
||||
dprintk("%s: case_insensitive=%s\n", __func__, *res == 0 ? "false" : "true");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_attr_case_preserving(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
|
||||
{
|
||||
__be32 *p;
|
||||
|
||||
*res = 0;
|
||||
if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_PRESERVING - 1U)))
|
||||
return -EIO;
|
||||
if (likely(bitmap[0] & FATTR4_WORD0_CASE_PRESERVING)) {
|
||||
p = xdr_inline_decode(xdr, 4);
|
||||
if (unlikely(!p))
|
||||
return -EIO;
|
||||
*res = be32_to_cpup(p);
|
||||
bitmap[0] &= ~FATTR4_WORD0_CASE_PRESERVING;
|
||||
}
|
||||
dprintk("%s: case_preserving=%s\n", __func__, *res == 0 ? "false" : "true");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
|
||||
{
|
||||
__be32 *p;
|
||||
@ -3696,8 +3732,6 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
|
||||
if (unlikely(!p))
|
||||
goto out_eio;
|
||||
n = be32_to_cpup(p);
|
||||
if (n <= 0)
|
||||
goto out_eio;
|
||||
for (res->nlocations = 0; res->nlocations < n; res->nlocations++) {
|
||||
u32 m;
|
||||
struct nfs4_fs_location *loc;
|
||||
@ -4200,10 +4234,11 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
|
||||
} else
|
||||
printk(KERN_WARNING "%s: label too long (%u)!\n",
|
||||
__func__, len);
|
||||
if (label && label->label)
|
||||
dprintk("%s: label=%.*s, len=%d, PI=%d, LFS=%d\n",
|
||||
__func__, label->len, (char *)label->label,
|
||||
label->len, label->pi, label->lfs);
|
||||
}
|
||||
if (label && label->label)
|
||||
dprintk("%s: label=%s, len=%d, PI=%d, LFS=%d\n", __func__,
|
||||
(char *)label->label, label->len, label->pi, label->lfs);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -4412,6 +4447,10 @@ static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_re
|
||||
goto xdr_error;
|
||||
if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
|
||||
goto xdr_error;
|
||||
if ((status = decode_attr_case_insensitive(xdr, bitmap, &res->case_insensitive)) != 0)
|
||||
goto xdr_error;
|
||||
if ((status = decode_attr_case_preserving(xdr, bitmap, &res->case_preserving)) != 0)
|
||||
goto xdr_error;
|
||||
if ((status = decode_attr_exclcreat_supported(xdr, bitmap,
|
||||
res->exclcreat_bitmask)) != 0)
|
||||
goto xdr_error;
|
||||
|
@ -142,10 +142,11 @@ static struct attribute *nfs_netns_client_attrs[] = {
|
||||
&nfs_netns_client_id.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(nfs_netns_client);
|
||||
|
||||
static struct kobj_type nfs_netns_client_type = {
|
||||
.release = nfs_netns_client_release,
|
||||
.default_attrs = nfs_netns_client_attrs,
|
||||
.default_groups = nfs_netns_client_groups,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
.namespace = nfs_netns_client_namespace,
|
||||
};
|
||||
|
@ -61,7 +61,9 @@
|
||||
struct nfs_access_entry {
|
||||
struct rb_node rb_node;
|
||||
struct list_head lru;
|
||||
const struct cred * cred;
|
||||
kuid_t fsuid;
|
||||
kgid_t fsgid;
|
||||
struct group_info *group_info;
|
||||
__u32 mask;
|
||||
struct rcu_head rcu_head;
|
||||
};
|
||||
@ -395,7 +397,7 @@ extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fa
|
||||
extern int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr);
|
||||
extern int nfs_getattr(struct user_namespace *, const struct path *,
|
||||
struct kstat *, u32, unsigned int);
|
||||
extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
|
||||
extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *, const struct cred *);
|
||||
extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
|
||||
extern int nfs_permission(struct user_namespace *, struct inode *, int);
|
||||
extern int nfs_open(struct inode *, struct file *);
|
||||
@ -532,8 +534,8 @@ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
|
||||
struct nfs_fattr *fattr);
|
||||
extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
|
||||
extern void nfs_access_zap_cache(struct inode *inode);
|
||||
extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res,
|
||||
bool may_block);
|
||||
extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred,
|
||||
u32 *mask, bool may_block);
|
||||
|
||||
/*
|
||||
* linux/fs/nfs/symlink.c
|
||||
|
@ -266,6 +266,8 @@ struct nfs_server {
|
||||
#define NFS_CAP_ACLS (1U << 3)
|
||||
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
|
||||
#define NFS_CAP_LGOPEN (1U << 5)
|
||||
#define NFS_CAP_CASE_INSENSITIVE (1U << 6)
|
||||
#define NFS_CAP_CASE_PRESERVING (1U << 7)
|
||||
#define NFS_CAP_POSIX_LOCK (1U << 14)
|
||||
#define NFS_CAP_UIDGID_NOMAP (1U << 15)
|
||||
#define NFS_CAP_STATEID_NFSV41 (1U << 16)
|
||||
@ -282,5 +284,5 @@ struct nfs_server {
|
||||
#define NFS_CAP_COPY_NOTIFY (1U << 27)
|
||||
#define NFS_CAP_XATTR (1U << 28)
|
||||
#define NFS_CAP_READ_PLUS (1U << 29)
|
||||
|
||||
#define NFS_CAP_FS_LOCATIONS (1U << 30)
|
||||
#endif
|
||||
|
@ -1194,6 +1194,8 @@ struct nfs4_server_caps_res {
|
||||
u32 has_links;
|
||||
u32 has_symlinks;
|
||||
u32 fh_expire_type;
|
||||
u32 case_insensitive;
|
||||
u32 case_preserving;
|
||||
};
|
||||
|
||||
#define NFS4_PATHNAME_MAXCOMPONENTS 512
|
||||
@ -1737,7 +1739,7 @@ struct nfs_rpc_ops {
|
||||
struct nfs_fh *, struct nfs_fattr *);
|
||||
int (*lookupp) (struct inode *, struct nfs_fh *,
|
||||
struct nfs_fattr *);
|
||||
int (*access) (struct inode *, struct nfs_access_entry *);
|
||||
int (*access) (struct inode *, struct nfs_access_entry *, const struct cred *);
|
||||
int (*readlink)(struct inode *, struct page *, unsigned int,
|
||||
unsigned int);
|
||||
int (*create) (struct inode *, struct dentry *,
|
||||
@ -1795,6 +1797,7 @@ struct nfs_rpc_ops {
|
||||
struct nfs_server *(*create_server)(struct fs_context *);
|
||||
struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
|
||||
struct nfs_fattr *, rpc_authflavor_t);
|
||||
int (*discover_trunking)(struct nfs_server *, struct nfs_fh *);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -794,6 +794,9 @@ RPC_SHOW_SOCKET
|
||||
|
||||
RPC_SHOW_SOCK
|
||||
|
||||
|
||||
#include <trace/events/net_probe_common.h>
|
||||
|
||||
/*
|
||||
* Now redefine the EM() and EMe() macros to map the enums to the strings
|
||||
* that will be printed in the output.
|
||||
@ -816,27 +819,32 @@ DECLARE_EVENT_CLASS(xs_socket_event,
|
||||
__field(unsigned int, socket_state)
|
||||
__field(unsigned int, sock_state)
|
||||
__field(unsigned long long, ino)
|
||||
__string(dstaddr,
|
||||
xprt->address_strings[RPC_DISPLAY_ADDR])
|
||||
__string(dstport,
|
||||
xprt->address_strings[RPC_DISPLAY_PORT])
|
||||
__array(__u8, saddr, sizeof(struct sockaddr_in6))
|
||||
__array(__u8, daddr, sizeof(struct sockaddr_in6))
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
struct inode *inode = SOCK_INODE(socket);
|
||||
const struct sock *sk = socket->sk;
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
memset(__entry->saddr, 0, sizeof(struct sockaddr_in6));
|
||||
memset(__entry->daddr, 0, sizeof(struct sockaddr_in6));
|
||||
|
||||
TP_STORE_ADDR_PORTS(__entry, inet, sk);
|
||||
|
||||
__entry->socket_state = socket->state;
|
||||
__entry->sock_state = socket->sk->sk_state;
|
||||
__entry->ino = (unsigned long long)inode->i_ino;
|
||||
__assign_str(dstaddr,
|
||||
xprt->address_strings[RPC_DISPLAY_ADDR]);
|
||||
__assign_str(dstport,
|
||||
xprt->address_strings[RPC_DISPLAY_PORT]);
|
||||
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"socket:[%llu] dstaddr=%s/%s "
|
||||
"socket:[%llu] srcaddr=%pISpc dstaddr=%pISpc "
|
||||
"state=%u (%s) sk_state=%u (%s)",
|
||||
__entry->ino, __get_str(dstaddr), __get_str(dstport),
|
||||
__entry->ino,
|
||||
__entry->saddr,
|
||||
__entry->daddr,
|
||||
__entry->socket_state,
|
||||
rpc_show_socket_state(__entry->socket_state),
|
||||
__entry->sock_state,
|
||||
@ -866,29 +874,33 @@ DECLARE_EVENT_CLASS(xs_socket_event_done,
|
||||
__field(unsigned int, socket_state)
|
||||
__field(unsigned int, sock_state)
|
||||
__field(unsigned long long, ino)
|
||||
__string(dstaddr,
|
||||
xprt->address_strings[RPC_DISPLAY_ADDR])
|
||||
__string(dstport,
|
||||
xprt->address_strings[RPC_DISPLAY_PORT])
|
||||
__array(__u8, saddr, sizeof(struct sockaddr_in6))
|
||||
__array(__u8, daddr, sizeof(struct sockaddr_in6))
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
struct inode *inode = SOCK_INODE(socket);
|
||||
const struct sock *sk = socket->sk;
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
memset(__entry->saddr, 0, sizeof(struct sockaddr_in6));
|
||||
memset(__entry->daddr, 0, sizeof(struct sockaddr_in6));
|
||||
|
||||
TP_STORE_ADDR_PORTS(__entry, inet, sk);
|
||||
|
||||
__entry->socket_state = socket->state;
|
||||
__entry->sock_state = socket->sk->sk_state;
|
||||
__entry->ino = (unsigned long long)inode->i_ino;
|
||||
__entry->error = error;
|
||||
__assign_str(dstaddr,
|
||||
xprt->address_strings[RPC_DISPLAY_ADDR]);
|
||||
__assign_str(dstport,
|
||||
xprt->address_strings[RPC_DISPLAY_PORT]);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"error=%d socket:[%llu] dstaddr=%s/%s "
|
||||
"error=%d socket:[%llu] srcaddr=%pISpc dstaddr=%pISpc "
|
||||
"state=%u (%s) sk_state=%u (%s)",
|
||||
__entry->error,
|
||||
__entry->ino, __get_str(dstaddr), __get_str(dstport),
|
||||
__entry->ino,
|
||||
__entry->saddr,
|
||||
__entry->daddr,
|
||||
__entry->socket_state,
|
||||
rpc_show_socket_state(__entry->socket_state),
|
||||
__entry->sock_state,
|
||||
@ -953,7 +965,8 @@ TRACE_EVENT(rpc_socket_nospace,
|
||||
{ BIT(XPRT_REMOVE), "REMOVE" }, \
|
||||
{ BIT(XPRT_CONGESTED), "CONGESTED" }, \
|
||||
{ BIT(XPRT_CWND_WAIT), "CWND_WAIT" }, \
|
||||
{ BIT(XPRT_WRITE_SPACE), "WRITE_SPACE" })
|
||||
{ BIT(XPRT_WRITE_SPACE), "WRITE_SPACE" }, \
|
||||
{ BIT(XPRT_SND_IS_COOKIE), "SND_IS_COOKIE" })
|
||||
|
||||
DECLARE_EVENT_CLASS(rpc_xprt_lifetime_class,
|
||||
TP_PROTO(
|
||||
@ -1150,8 +1163,11 @@ DECLARE_EVENT_CLASS(xprt_writelock_event,
|
||||
__entry->task_id = -1;
|
||||
__entry->client_id = -1;
|
||||
}
|
||||
__entry->snd_task_id = xprt->snd_task ?
|
||||
xprt->snd_task->tk_pid : -1;
|
||||
if (xprt->snd_task &&
|
||||
!test_bit(XPRT_SND_IS_COOKIE, &xprt->state))
|
||||
__entry->snd_task_id = xprt->snd_task->tk_pid;
|
||||
else
|
||||
__entry->snd_task_id = -1;
|
||||
),
|
||||
|
||||
TP_printk(SUNRPC_TRACE_TASK_SPECIFIER
|
||||
@ -1196,8 +1212,12 @@ DECLARE_EVENT_CLASS(xprt_cong_event,
|
||||
__entry->task_id = -1;
|
||||
__entry->client_id = -1;
|
||||
}
|
||||
__entry->snd_task_id = xprt->snd_task ?
|
||||
xprt->snd_task->tk_pid : -1;
|
||||
if (xprt->snd_task &&
|
||||
!test_bit(XPRT_SND_IS_COOKIE, &xprt->state))
|
||||
__entry->snd_task_id = xprt->snd_task->tk_pid;
|
||||
else
|
||||
__entry->snd_task_id = -1;
|
||||
|
||||
__entry->cong = xprt->cong;
|
||||
__entry->cwnd = xprt->cwnd;
|
||||
__entry->wait = test_bit(XPRT_CWND_WAIT, &xprt->state);
|
||||
|
@ -222,10 +222,8 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ret) {
|
||||
*buf_in = buf;
|
||||
*body_size = toksize;
|
||||
}
|
||||
*buf_in = buf;
|
||||
*body_size = toksize;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2900,7 +2900,7 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
|
||||
unsigned long connect_timeout;
|
||||
unsigned long reconnect_timeout;
|
||||
unsigned char resvport, reuseport;
|
||||
int ret = 0;
|
||||
int ret = 0, ident;
|
||||
|
||||
rcu_read_lock();
|
||||
xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
|
||||
@ -2914,8 +2914,11 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
|
||||
reuseport = xprt->reuseport;
|
||||
connect_timeout = xprt->connect_timeout;
|
||||
reconnect_timeout = xprt->max_reconnect_timeout;
|
||||
ident = xprt->xprt_class->ident;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!xprtargs->ident)
|
||||
xprtargs->ident = ident;
|
||||
xprt = xprt_create_transport(xprtargs);
|
||||
if (IS_ERR(xprt)) {
|
||||
ret = PTR_ERR(xprt);
|
||||
|
@ -295,8 +295,10 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
|
||||
online = 1;
|
||||
else if (!strncmp(buf, "remove", 6))
|
||||
remove = 1;
|
||||
else
|
||||
return -EINVAL;
|
||||
else {
|
||||
count = -EINVAL;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE)) {
|
||||
count = -EINTR;
|
||||
@ -307,25 +309,28 @@ static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
|
||||
goto release_tasks;
|
||||
}
|
||||
if (offline) {
|
||||
set_bit(XPRT_OFFLINE, &xprt->state);
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive--;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
if (!test_and_set_bit(XPRT_OFFLINE, &xprt->state)) {
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive--;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
}
|
||||
} else if (online) {
|
||||
clear_bit(XPRT_OFFLINE, &xprt->state);
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive++;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
if (test_and_clear_bit(XPRT_OFFLINE, &xprt->state)) {
|
||||
spin_lock(&xps->xps_lock);
|
||||
xps->xps_nactive++;
|
||||
spin_unlock(&xps->xps_lock);
|
||||
}
|
||||
} else if (remove) {
|
||||
if (test_bit(XPRT_OFFLINE, &xprt->state)) {
|
||||
set_bit(XPRT_REMOVE, &xprt->state);
|
||||
xprt_force_disconnect(xprt);
|
||||
if (test_bit(XPRT_CONNECTED, &xprt->state)) {
|
||||
if (!xprt->sending.qlen &&
|
||||
!xprt->pending.qlen &&
|
||||
!xprt->backlog.qlen &&
|
||||
!atomic_long_read(&xprt->queuelen))
|
||||
rpc_xprt_switch_remove_xprt(xps, xprt);
|
||||
if (!test_and_set_bit(XPRT_REMOVE, &xprt->state)) {
|
||||
xprt_force_disconnect(xprt);
|
||||
if (test_bit(XPRT_CONNECTED, &xprt->state)) {
|
||||
if (!xprt->sending.qlen &&
|
||||
!xprt->pending.qlen &&
|
||||
!xprt->backlog.qlen &&
|
||||
!atomic_long_read(&xprt->queuelen))
|
||||
rpc_xprt_switch_remove_xprt(xps, xprt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
count = -EINVAL;
|
||||
@ -422,6 +427,7 @@ static struct attribute *rpc_sysfs_xprt_attrs[] = {
|
||||
&rpc_sysfs_xprt_change_state.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(rpc_sysfs_xprt);
|
||||
|
||||
static struct kobj_attribute rpc_sysfs_xprt_switch_info =
|
||||
__ATTR(xprt_switch_info, 0444, rpc_sysfs_xprt_switch_info_show, NULL);
|
||||
@ -430,6 +436,7 @@ static struct attribute *rpc_sysfs_xprt_switch_attrs[] = {
|
||||
&rpc_sysfs_xprt_switch_info.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(rpc_sysfs_xprt_switch);
|
||||
|
||||
static struct kobj_type rpc_sysfs_client_type = {
|
||||
.release = rpc_sysfs_client_release,
|
||||
@ -439,14 +446,14 @@ static struct kobj_type rpc_sysfs_client_type = {
|
||||
|
||||
static struct kobj_type rpc_sysfs_xprt_switch_type = {
|
||||
.release = rpc_sysfs_xprt_switch_release,
|
||||
.default_attrs = rpc_sysfs_xprt_switch_attrs,
|
||||
.default_groups = rpc_sysfs_xprt_switch_groups,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
.namespace = rpc_sysfs_xprt_switch_namespace,
|
||||
};
|
||||
|
||||
static struct kobj_type rpc_sysfs_xprt_type = {
|
||||
.release = rpc_sysfs_xprt_release,
|
||||
.default_attrs = rpc_sysfs_xprt_attrs,
|
||||
.default_groups = rpc_sysfs_xprt_groups,
|
||||
.sysfs_ops = &kobj_sysfs_ops,
|
||||
.namespace = rpc_sysfs_xprt_namespace,
|
||||
};
|
||||
|
@ -13,10 +13,6 @@
|
||||
#include "xprt_rdma.h"
|
||||
#include <trace/events/rpcrdma.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
#undef RPCRDMA_BACKCHANNEL_DEBUG
|
||||
|
||||
/**
|
||||
|
@ -45,10 +45,6 @@
|
||||
#include "xprt_rdma.h"
|
||||
#include <trace/events/rpcrdma.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
static void frwr_cid_init(struct rpcrdma_ep *ep,
|
||||
struct rpcrdma_mr *mr)
|
||||
{
|
||||
|
@ -54,10 +54,6 @@
|
||||
#include "xprt_rdma.h"
|
||||
#include <trace/events/rpcrdma.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
/* Returns size of largest RPC-over-RDMA header in a Call message
|
||||
*
|
||||
* The largest Call header contains a full-size Read list and a
|
||||
|
@ -60,10 +60,6 @@
|
||||
#include "xprt_rdma.h"
|
||||
#include <trace/events/rpcrdma.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* tunables
|
||||
*/
|
||||
|
@ -63,17 +63,6 @@
|
||||
#include "xprt_rdma.h"
|
||||
#include <trace/events/rpcrdma.h>
|
||||
|
||||
/*
|
||||
* Globals/Macros
|
||||
*/
|
||||
|
||||
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
|
||||
# define RPCDBG_FACILITY RPCDBG_TRANS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* internal functions
|
||||
*/
|
||||
static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt);
|
||||
static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt);
|
||||
static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
|
||||
@ -274,8 +263,6 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
|
||||
ep->re_connect_status = -ENETUNREACH;
|
||||
goto wake_connect_worker;
|
||||
case RDMA_CM_EVENT_REJECTED:
|
||||
dprintk("rpcrdma: connection to %pISpc rejected: %s\n",
|
||||
sap, rdma_reject_msg(id, event->status));
|
||||
ep->re_connect_status = -ECONNREFUSED;
|
||||
if (event->status == IB_CM_REJ_STALE_CONN)
|
||||
ep->re_connect_status = -ENOTCONN;
|
||||
@ -291,8 +278,6 @@ disconnected:
|
||||
break;
|
||||
}
|
||||
|
||||
dprintk("RPC: %s: %pISpc on %s/frwr: %s\n", __func__, sap,
|
||||
ep->re_id->device->name, rdma_event_msg(event->event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -419,14 +404,6 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
|
||||
ep->re_attr.qp_type = IB_QPT_RC;
|
||||
ep->re_attr.port_num = ~0;
|
||||
|
||||
dprintk("RPC: %s: requested max: dtos: send %d recv %d; "
|
||||
"iovs: send %d recv %d\n",
|
||||
__func__,
|
||||
ep->re_attr.cap.max_send_wr,
|
||||
ep->re_attr.cap.max_recv_wr,
|
||||
ep->re_attr.cap.max_send_sge,
|
||||
ep->re_attr.cap.max_recv_sge);
|
||||
|
||||
ep->re_send_batch = ep->re_max_requests >> 3;
|
||||
ep->re_send_count = ep->re_send_batch;
|
||||
init_waitqueue_head(&ep->re_connect_wait);
|
||||
|
@ -1910,7 +1910,7 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
||||
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
||||
int ret;
|
||||
|
||||
if (RPC_IS_ASYNC(task)) {
|
||||
if (RPC_IS_ASYNC(task)) {
|
||||
/*
|
||||
* We want the AF_LOCAL connect to be resolved in the
|
||||
* filesystem namespace of the process making the rpc
|
||||
|
Loading…
Reference in New Issue
Block a user