diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2018-06-02 18:08:11 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-06-02 18:09:27 -0400 |
| commit | de52cf922a4a17d0a4cd34d697db62a01c1bd092 (patch) | |
| tree | 1c12675d523eaa34e01499ae2a70dc6983a1918b | |
| parent | 5b86d4ff5dce3271dff54119e06174dc22422903 (diff) | |
| parent | 4776cab43fd3111618112737a257dc3ef368eddd (diff) | |
Merge tag 'afs-fixes-20180514' into afs-proc
backmerge AFS fixes that went into mainline and deal with
the conflict in fs/afs/fsclient.c
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/afs/addr_list.c | 25 | ||||
| -rw-r--r-- | fs/afs/callback.c | 84 | ||||
| -rw-r--r-- | fs/afs/cmservice.c | 67 | ||||
| -rw-r--r-- | fs/afs/dir.c | 54 | ||||
| -rw-r--r-- | fs/afs/file.c | 2 | ||||
| -rw-r--r-- | fs/afs/flock.c | 6 | ||||
| -rw-r--r-- | fs/afs/fsclient.c | 28 | ||||
| -rw-r--r-- | fs/afs/inode.c | 19 | ||||
| -rw-r--r-- | fs/afs/internal.h | 25 | ||||
| -rw-r--r-- | fs/afs/rotate.c | 20 | ||||
| -rw-r--r-- | fs/afs/rxrpc.c | 18 | ||||
| -rw-r--r-- | fs/afs/security.c | 7 | ||||
| -rw-r--r-- | fs/afs/server.c | 21 | ||||
| -rw-r--r-- | fs/afs/server_list.c | 7 | ||||
| -rw-r--r-- | fs/afs/super.c | 4 | ||||
| -rw-r--r-- | fs/afs/write.c | 2 | ||||
| -rw-r--r-- | include/trace/events/afs.h | 42 |
17 files changed, 264 insertions, 167 deletions
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c index 3bedfed608a2..7587fb665ff1 100644 --- a/fs/afs/addr_list.c +++ b/fs/afs/addr_list.c | |||
| @@ -121,7 +121,7 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len, | |||
| 121 | p = text; | 121 | p = text; |
| 122 | do { | 122 | do { |
| 123 | struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs]; | 123 | struct sockaddr_rxrpc *srx = &alist->addrs[alist->nr_addrs]; |
| 124 | char tdelim = delim; | 124 | const char *q, *stop; |
| 125 | 125 | ||
| 126 | if (*p == delim) { | 126 | if (*p == delim) { |
| 127 | p++; | 127 | p++; |
| @@ -130,28 +130,33 @@ struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len, | |||
| 130 | 130 | ||
| 131 | if (*p == '[') { | 131 | if (*p == '[') { |
| 132 | p++; | 132 | p++; |
| 133 | tdelim = ']'; | 133 | q = memchr(p, ']', end - p); |
| 134 | } else { | ||
| 135 | for (q = p; q < end; q++) | ||
| 136 | if (*q == '+' || *q == delim) | ||
| 137 | break; | ||
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | if (in4_pton(p, end - p, | 140 | if (in4_pton(p, q - p, |
| 137 | (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3], | 141 | (u8 *)&srx->transport.sin6.sin6_addr.s6_addr32[3], |
| 138 | tdelim, &p)) { | 142 | -1, &stop)) { |
| 139 | srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; | 143 | srx->transport.sin6.sin6_addr.s6_addr32[0] = 0; |
| 140 | srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; | 144 | srx->transport.sin6.sin6_addr.s6_addr32[1] = 0; |
| 141 | srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | 145 | srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); |
| 142 | } else if (in6_pton(p, end - p, | 146 | } else if (in6_pton(p, q - p, |
| 143 | srx->transport.sin6.sin6_addr.s6_addr, | 147 | srx->transport.sin6.sin6_addr.s6_addr, |
| 144 | tdelim, &p)) { | 148 | -1, &stop)) { |
| 145 | /* Nothing to do */ | 149 | /* Nothing to do */ |
| 146 | } else { | 150 | } else { |
| 147 | goto bad_address; | 151 | goto bad_address; |
| 148 | } | 152 | } |
| 149 | 153 | ||
| 150 | if (tdelim == ']') { | 154 | if (stop != q) |
| 151 | if (p == end || *p != ']') | 155 | goto bad_address; |
| 152 | goto bad_address; | 156 | |
| 157 | p = q; | ||
| 158 | if (q < end && *q == ']') | ||
| 153 | p++; | 159 | p++; |
| 154 | } | ||
| 155 | 160 | ||
| 156 | if (p < end) { | 161 | if (p < end) { |
| 157 | if (*p == '+') { | 162 | if (*p == '+') { |
diff --git a/fs/afs/callback.c b/fs/afs/callback.c index abd9a84f4e88..571437dcb252 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c | |||
| @@ -23,36 +23,55 @@ | |||
| 23 | /* | 23 | /* |
| 24 | * Set up an interest-in-callbacks record for a volume on a server and | 24 | * Set up an interest-in-callbacks record for a volume on a server and |
| 25 | * register it with the server. | 25 | * register it with the server. |
| 26 | * - Called with volume->server_sem held. | 26 | * - Called with vnode->io_lock held. |
| 27 | */ | 27 | */ |
| 28 | int afs_register_server_cb_interest(struct afs_vnode *vnode, | 28 | int afs_register_server_cb_interest(struct afs_vnode *vnode, |
| 29 | struct afs_server_entry *entry) | 29 | struct afs_server_list *slist, |
| 30 | unsigned int index) | ||
| 30 | { | 31 | { |
| 31 | struct afs_cb_interest *cbi = entry->cb_interest, *vcbi, *new, *x; | 32 | struct afs_server_entry *entry = &slist->servers[index]; |
| 33 | struct afs_cb_interest *cbi, *vcbi, *new, *old; | ||
| 32 | struct afs_server *server = entry->server; | 34 | struct afs_server *server = entry->server; |
| 33 | 35 | ||
| 34 | again: | 36 | again: |
| 37 | if (vnode->cb_interest && | ||
| 38 | likely(vnode->cb_interest == entry->cb_interest)) | ||
| 39 | return 0; | ||
| 40 | |||
| 41 | read_lock(&slist->lock); | ||
| 42 | cbi = afs_get_cb_interest(entry->cb_interest); | ||
| 43 | read_unlock(&slist->lock); | ||
| 44 | |||
| 35 | vcbi = vnode->cb_interest; | 45 | vcbi = vnode->cb_interest; |
| 36 | if (vcbi) { | 46 | if (vcbi) { |
| 37 | if (vcbi == cbi) | 47 | if (vcbi == cbi) { |
| 48 | afs_put_cb_interest(afs_v2net(vnode), cbi); | ||
| 38 | return 0; | 49 | return 0; |
| 50 | } | ||
| 39 | 51 | ||
| 52 | /* Use a new interest in the server list for the same server | ||
| 53 | * rather than an old one that's still attached to a vnode. | ||
| 54 | */ | ||
| 40 | if (cbi && vcbi->server == cbi->server) { | 55 | if (cbi && vcbi->server == cbi->server) { |
| 41 | write_seqlock(&vnode->cb_lock); | 56 | write_seqlock(&vnode->cb_lock); |
| 42 | vnode->cb_interest = afs_get_cb_interest(cbi); | 57 | old = vnode->cb_interest; |
| 58 | vnode->cb_interest = cbi; | ||
| 43 | write_sequnlock(&vnode->cb_lock); | 59 | write_sequnlock(&vnode->cb_lock); |
| 44 | afs_put_cb_interest(afs_v2net(vnode), cbi); | 60 | afs_put_cb_interest(afs_v2net(vnode), old); |
| 45 | return 0; | 61 | return 0; |
| 46 | } | 62 | } |
| 47 | 63 | ||
| 64 | /* Re-use the one attached to the vnode. */ | ||
| 48 | if (!cbi && vcbi->server == server) { | 65 | if (!cbi && vcbi->server == server) { |
| 49 | afs_get_cb_interest(vcbi); | 66 | write_lock(&slist->lock); |
| 50 | x = cmpxchg(&entry->cb_interest, cbi, vcbi); | 67 | if (entry->cb_interest) { |
| 51 | if (x != cbi) { | 68 | write_unlock(&slist->lock); |
| 52 | cbi = x; | 69 | afs_put_cb_interest(afs_v2net(vnode), cbi); |
| 53 | afs_put_cb_interest(afs_v2net(vnode), vcbi); | ||
| 54 | goto again; | 70 | goto again; |
| 55 | } | 71 | } |
| 72 | |||
| 73 | entry->cb_interest = cbi; | ||
| 74 | write_unlock(&slist->lock); | ||
| 56 | return 0; | 75 | return 0; |
| 57 | } | 76 | } |
| 58 | } | 77 | } |
| @@ -72,13 +91,16 @@ again: | |||
| 72 | list_add_tail(&new->cb_link, &server->cb_interests); | 91 | list_add_tail(&new->cb_link, &server->cb_interests); |
| 73 | write_unlock(&server->cb_break_lock); | 92 | write_unlock(&server->cb_break_lock); |
| 74 | 93 | ||
| 75 | x = cmpxchg(&entry->cb_interest, cbi, new); | 94 | write_lock(&slist->lock); |
| 76 | if (x == cbi) { | 95 | if (!entry->cb_interest) { |
| 96 | entry->cb_interest = afs_get_cb_interest(new); | ||
| 77 | cbi = new; | 97 | cbi = new; |
| 98 | new = NULL; | ||
| 78 | } else { | 99 | } else { |
| 79 | cbi = x; | 100 | cbi = afs_get_cb_interest(entry->cb_interest); |
| 80 | afs_put_cb_interest(afs_v2net(vnode), new); | ||
| 81 | } | 101 | } |
| 102 | write_unlock(&slist->lock); | ||
| 103 | afs_put_cb_interest(afs_v2net(vnode), new); | ||
| 82 | } | 104 | } |
| 83 | 105 | ||
| 84 | ASSERT(cbi); | 106 | ASSERT(cbi); |
| @@ -88,11 +110,14 @@ again: | |||
| 88 | */ | 110 | */ |
| 89 | write_seqlock(&vnode->cb_lock); | 111 | write_seqlock(&vnode->cb_lock); |
| 90 | 112 | ||
| 91 | vnode->cb_interest = afs_get_cb_interest(cbi); | 113 | old = vnode->cb_interest; |
| 114 | vnode->cb_interest = cbi; | ||
| 92 | vnode->cb_s_break = cbi->server->cb_s_break; | 115 | vnode->cb_s_break = cbi->server->cb_s_break; |
| 116 | vnode->cb_v_break = vnode->volume->cb_v_break; | ||
| 93 | clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); | 117 | clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); |
| 94 | 118 | ||
| 95 | write_sequnlock(&vnode->cb_lock); | 119 | write_sequnlock(&vnode->cb_lock); |
| 120 | afs_put_cb_interest(afs_v2net(vnode), old); | ||
| 96 | return 0; | 121 | return 0; |
| 97 | } | 122 | } |
| 98 | 123 | ||
| @@ -171,13 +196,24 @@ static void afs_break_one_callback(struct afs_server *server, | |||
| 171 | if (cbi->vid != fid->vid) | ||
