Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'work.afs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull AFS updates from Al Viro:
"AFS series, with some iov_iter bits included"

* 'work.afs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (26 commits)
missing bits of "iov_iter: Separate type from direction and use accessor functions"
afs: Probe multiple fileservers simultaneously
afs: Fix callback handling
afs: Eliminate the address pointer from the address list cursor
afs: Allow dumping of server cursor on operation failure
afs: Implement YFS support in the fs client
afs: Expand data structure fields to support YFS
afs: Get the target vnode in afs_rmdir() and get a callback on it
afs: Calc callback expiry in op reply delivery
afs: Fix FS.FetchStatus delivery from updating wrong vnode
afs: Implement the YFS cache manager service
afs: Remove callback details from afs_callback_break struct
afs: Commit the status on a new file/dir/symlink
afs: Increase to 64-bit volume ID and 96-bit vnode ID for YFS
afs: Don't invoke the server to read data beyond EOF
afs: Add a couple of tracepoints to log I/O errors
afs: Handle EIO from delivery function
afs: Fix TTL on VL server and address lists
afs: Implement VL server rotation
afs: Improve FS server rotation error handling
...

+5631 -1238
+1 -1
block/bio.c
··· 1256 1256 /* 1257 1257 * success 1258 1258 */ 1259 - if (((iter->type & WRITE) && (!map_data || !map_data->null_mapped)) || 1259 + if ((iov_iter_rw(iter) == WRITE && (!map_data || !map_data->null_mapped)) || 1260 1260 (map_data && map_data->from_user)) { 1261 1261 ret = bio_copy_from_iter(bio, iter); 1262 1262 if (ret)
+1 -1
drivers/block/drbd/drbd_main.c
··· 1856 1856 1857 1857 /* THINK if (signal_pending) return ... ? */ 1858 1858 1859 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iov, 1, size); 1859 + iov_iter_kvec(&msg.msg_iter, WRITE, &iov, 1, size); 1860 1860 1861 1861 if (sock == connection->data.socket) { 1862 1862 rcu_read_lock();
+1 -1
drivers/block/drbd/drbd_receiver.c
··· 516 516 struct msghdr msg = { 517 517 .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL) 518 518 }; 519 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, size); 519 + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, size); 520 520 return sock_recvmsg(sock, &msg, msg.msg_flags); 521 521 } 522 522
+4 -5
drivers/block/loop.c
··· 269 269 struct iov_iter i; 270 270 ssize_t bw; 271 271 272 - iov_iter_bvec(&i, ITER_BVEC | WRITE, bvec, 1, bvec->bv_len); 272 + iov_iter_bvec(&i, WRITE, bvec, 1, bvec->bv_len); 273 273 274 274 file_start_write(file); 275 275 bw = vfs_iter_write(file, &i, ppos, 0); ··· 347 347 ssize_t len; 348 348 349 349 rq_for_each_segment(bvec, rq, iter) { 350 - iov_iter_bvec(&i, ITER_BVEC, &bvec, 1, bvec.bv_len); 350 + iov_iter_bvec(&i, READ, &bvec, 1, bvec.bv_len); 351 351 len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0); 352 352 if (len < 0) 353 353 return len; ··· 388 388 b.bv_offset = 0; 389 389 b.bv_len = bvec.bv_len; 390 390 391 - iov_iter_bvec(&i, ITER_BVEC, &b, 1, b.bv_len); 391 + iov_iter_bvec(&i, READ, &b, 1, b.bv_len); 392 392 len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0); 393 393 if (len < 0) { 394 394 ret = len; ··· 555 555 } 556 556 atomic_set(&cmd->ref, 2); 557 557 558 - iov_iter_bvec(&iter, ITER_BVEC | rw, bvec, 559 - segments, blk_rq_bytes(rq)); 558 + iov_iter_bvec(&iter, rw, bvec, segments, blk_rq_bytes(rq)); 560 559 iter.iov_offset = offset; 561 560 562 561 cmd->iocb.ki_pos = pos;
+5 -7
drivers/block/nbd.c
··· 473 473 u32 nbd_cmd_flags = 0; 474 474 int sent = nsock->sent, skip = 0; 475 475 476 - iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request)); 476 + iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); 477 477 478 478 switch (req_op(req)) { 479 479 case REQ_OP_DISCARD: ··· 564 564 565 565 dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n", 566 566 req, bvec.bv_len); 567 - iov_iter_bvec(&from, ITER_BVEC | WRITE, 568 - &bvec, 1, bvec.bv_len); 567 + iov_iter_bvec(&from, WRITE, &bvec, 1, bvec.bv_len); 569 568 if (skip) { 570 569 if (skip >= iov_iter_count(&from)) { 571 570 skip -= iov_iter_count(&from); ··· 623 624 int ret = 0; 624 625 625 626 reply.magic = 0; 626 - iov_iter_kvec(&to, READ | ITER_KVEC, &iov, 1, sizeof(reply)); 627 + iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply)); 627 628 result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); 628 629 if (result <= 0) { 629 630 if (!nbd_disconnected(config)) ··· 677 678 struct bio_vec bvec; 678 679 679 680 rq_for_each_segment(bvec, req, iter) { 680 - iov_iter_bvec(&to, ITER_BVEC | READ, 681 - &bvec, 1, bvec.bv_len); 681 + iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); 682 682 result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); 683 683 if (result <= 0) { 684 684 dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n", ··· 1071 1073 for (i = 0; i < config->num_connections; i++) { 1072 1074 struct nbd_sock *nsock = config->socks[i]; 1073 1075 1074 - iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request)); 1076 + iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); 1075 1077 mutex_lock(&nsock->tx_lock); 1076 1078 ret = sock_xmit(nbd, i, 1, &from, 0, NULL); 1077 1079 if (ret <= 0)
+2 -2
drivers/fsi/fsi-sbefifo.c
··· 638 638 } 639 639 ffdc_iov.iov_base = ffdc; 640 640 ffdc_iov.iov_len = SBEFIFO_MAX_FFDC_SIZE; 641 - iov_iter_kvec(&ffdc_iter, WRITE | ITER_KVEC, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); 641 + iov_iter_kvec(&ffdc_iter, WRITE, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); 642 642 cmd[0] = cpu_to_be32(2); 643 643 cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_SBE_FFDC); 644 644 rc = sbefifo_do_command(sbefifo, cmd, 2, &ffdc_iter); ··· 735 735 rbytes = (*resp_len) * sizeof(__be32); 736 736 resp_iov.iov_base = response; 737 737 resp_iov.iov_len = rbytes; 738 - iov_iter_kvec(&resp_iter, WRITE | ITER_KVEC, &resp_iov, 1, rbytes); 738 + iov_iter_kvec(&resp_iter, WRITE, &resp_iov, 1, rbytes); 739 739 740 740 /* Perform the command */ 741 741 mutex_lock(&sbefifo->lock);
-2
drivers/gpu/drm/amd/display/dc/os_types.h
··· 40 40 #define LITTLEENDIAN_CPU 41 41 #endif 42 42 43 - #undef READ 44 - #undef WRITE 45 43 #undef FRAME_SIZE 46 44 47 45 #define dm_output_to_console(fmt, ...) DRM_DEBUG_KMS(fmt, ##__VA_ARGS__)
+1 -2
drivers/isdn/mISDN/l1oip_core.c
··· 718 718 printk(KERN_DEBUG "%s: socket created and open\n", 719 719 __func__); 720 720 while (!signal_pending(current)) { 721 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, 722 - recvbuf_size); 721 + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, recvbuf_size); 723 722 recvlen = sock_recvmsg(socket, &msg, 0); 724 723 if (recvlen > 0) { 725 724 l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
+3 -3
drivers/misc/vmw_vmci/vmci_queue_pair.c
··· 3030 3030 if (!qpair || !buf) 3031 3031 return VMCI_ERROR_INVALID_ARGS; 3032 3032 3033 - iov_iter_kvec(&from, WRITE | ITER_KVEC, &v, 1, buf_size); 3033 + iov_iter_kvec(&from, WRITE, &v, 1, buf_size); 3034 3034 3035 3035 qp_lock(qpair); 3036 3036 ··· 3074 3074 if (!qpair || !buf) 3075 3075 return VMCI_ERROR_INVALID_ARGS; 3076 3076 3077 - iov_iter_kvec(&to, READ | ITER_KVEC, &v, 1, buf_size); 3077 + iov_iter_kvec(&to, READ, &v, 1, buf_size); 3078 3078 3079 3079 qp_lock(qpair); 3080 3080 ··· 3119 3119 if (!qpair || !buf) 3120 3120 return VMCI_ERROR_INVALID_ARGS; 3121 3121 3122 - iov_iter_kvec(&to, READ | ITER_KVEC, &v, 1, buf_size); 3122 + iov_iter_kvec(&to, READ, &v, 1, buf_size); 3123 3123 3124 3124 qp_lock(qpair); 3125 3125
+1 -1
drivers/nvme/target/io-cmd-file.c
··· 101 101 rw = READ; 102 102 } 103 103 104 - iov_iter_bvec(&iter, ITER_BVEC | rw, req->f.bvec, nr_segs, count); 104 + iov_iter_bvec(&iter, rw, req->f.bvec, nr_segs, count); 105 105 106 106 iocb->ki_pos = pos; 107 107 iocb->ki_filp = req->ns->file;
+2 -4
drivers/target/iscsi/iscsi_target_util.c
··· 1245 1245 return -1; 1246 1246 1247 1247 memset(&msg, 0, sizeof(struct msghdr)); 1248 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, 1249 - count->iov, count->iov_count, data); 1248 + iov_iter_kvec(&msg.msg_iter, READ, count->iov, count->iov_count, data); 1250 1249 1251 1250 while (msg_data_left(&msg)) { 1252 1251 rx_loop = sock_recvmsg(conn->sock, &msg, MSG_WAITALL); ··· 1301 1302 1302 1303 memset(&msg, 0, sizeof(struct msghdr)); 1303 1304 1304 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, 1305 - iov, iov_count, data); 1305 + iov_iter_kvec(&msg.msg_iter, WRITE, iov, iov_count, data); 1306 1306 1307 1307 while (msg_data_left(&msg)) { 1308 1308 int tx_loop = sock_sendmsg(conn->sock, &msg);
+3 -3
drivers/target/target_core_file.c
··· 303 303 len += sg->length; 304 304 } 305 305 306 - iov_iter_bvec(&iter, ITER_BVEC | is_write, bvec, sgl_nents, len); 306 + iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len); 307 307 308 308 aio_cmd->cmd = cmd; 309 309 aio_cmd->len = len; ··· 353 353 len += sg->length; 354 354 } 355 355 356 - iov_iter_bvec(&iter, ITER_BVEC, bvec, sgl_nents, len); 356 + iov_iter_bvec(&iter, READ, bvec, sgl_nents, len); 357 357 if (is_write) 358 358 ret = vfs_iter_write(fd, &iter, &pos, 0); 359 359 else ··· 490 490 len += se_dev->dev_attrib.block_size; 491 491 } 492 492 493 - iov_iter_bvec(&iter, ITER_BVEC, bvec, nolb, len); 493 + iov_iter_bvec(&iter, READ, bvec, nolb, len); 494 494 ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0); 495 495 496 496 kfree(bvec);
+1 -1
drivers/usb/usbip/usbip_common.c
··· 309 309 if (!sock || !buf || !size) 310 310 return -EINVAL; 311 311 312 - iov_iter_kvec(&msg.msg_iter, READ|ITER_KVEC, &iov, 1, size); 312 + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, size); 313 313 314 314 usbip_dbg_xmit("enter\n"); 315 315
+4 -4
drivers/xen/pvcalls-back.c
··· 137 137 if (masked_prod < masked_cons) { 138 138 vec[0].iov_base = data->in + masked_prod; 139 139 vec[0].iov_len = wanted; 140 - iov_iter_kvec(&msg.msg_iter, ITER_KVEC|WRITE, vec, 1, wanted); 140 + iov_iter_kvec(&msg.msg_iter, WRITE, vec, 1, wanted); 141 141 } else { 142 142 vec[0].iov_base = data->in + masked_prod; 143 143 vec[0].iov_len = array_size - masked_prod; 144 144 vec[1].iov_base = data->in; 145 145 vec[1].iov_len = wanted - vec[0].iov_len; 146 - iov_iter_kvec(&msg.msg_iter, ITER_KVEC|WRITE, vec, 2, wanted); 146 + iov_iter_kvec(&msg.msg_iter, WRITE, vec, 2, wanted); 147 147 } 148 148 149 149 atomic_set(&map->read, 0); ··· 195 195 if (pvcalls_mask(prod, array_size) > pvcalls_mask(cons, array_size)) { 196 196 vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); 197 197 vec[0].iov_len = size; 198 - iov_iter_kvec(&msg.msg_iter, ITER_KVEC|READ, vec, 1, size); 198 + iov_iter_kvec(&msg.msg_iter, READ, vec, 1, size); 199 199 } else { 200 200 vec[0].iov_base = data->out + pvcalls_mask(cons, array_size); 201 201 vec[0].iov_len = array_size - pvcalls_mask(cons, array_size); 202 202 vec[1].iov_base = data->out; 203 203 vec[1].iov_len = size - vec[0].iov_len; 204 - iov_iter_kvec(&msg.msg_iter, ITER_KVEC|READ, vec, 2, size); 204 + iov_iter_kvec(&msg.msg_iter, READ, vec, 2, size); 205 205 } 206 206 207 207 atomic_set(&map->write, 0);
+2 -2
fs/9p/vfs_addr.c
··· 65 65 if (retval == 0) 66 66 return retval; 67 67 68 - iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE); 68 + iov_iter_bvec(&to, READ, &bvec, 1, PAGE_SIZE); 69 69 70 70 retval = p9_client_read(fid, page_offset(page), &to, &err); 71 71 if (err) { ··· 175 175 bvec.bv_page = page; 176 176 bvec.bv_offset = 0; 177 177 bvec.bv_len = len; 178 - iov_iter_bvec(&from, ITER_BVEC | WRITE, &bvec, 1, len); 178 + iov_iter_bvec(&from, WRITE, &bvec, 1, len); 179 179 180 180 /* We should have writeback_fid always set */ 181 181 BUG_ON(!v9inode->writeback_fid);
+1 -1
fs/9p/vfs_dir.c
··· 123 123 if (rdir->tail == rdir->head) { 124 124 struct iov_iter to; 125 125 int n; 126 - iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buflen); 126 + iov_iter_kvec(&to, READ, &kvec, 1, buflen); 127 127 n = p9_client_read(file->private_data, ctx->pos, &to, 128 128 &err); 129 129 if (err)
+2 -2
fs/9p/xattr.c
··· 32 32 struct iov_iter to; 33 33 int err; 34 34 35 - iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buffer_size); 35 + iov_iter_kvec(&to, READ, &kvec, 1, buffer_size); 36 36 37 37 attr_fid = p9_client_xattrwalk(fid, name, &attr_size); 38 38 if (IS_ERR(attr_fid)) { ··· 107 107 struct iov_iter from; 108 108 int retval, err; 109 109 110 - iov_iter_kvec(&from, WRITE | ITER_KVEC, &kvec, 1, value_len); 110 + iov_iter_kvec(&from, WRITE, &kvec, 1, value_len); 111 111 112 112 p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n", 113 113 name, value_len, flags);
+12
fs/afs/Kconfig
··· 27 27 help 28 28 Say Y here if you want AFS data to be cached locally on disk through 29 29 the generic filesystem cache manager 30 + 31 + config AFS_DEBUG_CURSOR 32 + bool "AFS server cursor debugging" 33 + depends on AFS_FS 34 + help 35 + Say Y here to cause the contents of a server cursor to be dumped to 36 + the dmesg log if the server rotation algorithm fails to successfully 37 + contact a server. 38 + 39 + See <file:Documentation/filesystems/afs.txt> for more information. 40 + 41 + If unsure, say N.
+6 -1
fs/afs/Makefile
··· 17 17 file.o \ 18 18 flock.o \ 19 19 fsclient.o \ 20 + fs_probe.o \ 20 21 inode.o \ 21 22 main.o \ 22 23 misc.o \ ··· 30 29 super.o \ 31 30 netdevices.o \ 32 31 vlclient.o \ 32 + vl_list.o \ 33 + vl_probe.o \ 34 + vl_rotate.o \ 33 35 volume.o \ 34 36 write.o \ 35 - xattr.o 37 + xattr.o \ 38 + yfsclient.o 36 39 37 40 kafs-$(CONFIG_PROC_FS) += proc.o 38 41 obj-$(CONFIG_AFS_FS) := kafs.o
+114 -97
fs/afs/addr_list.c
··· 64 64 /* 65 65 * Parse a text string consisting of delimited addresses. 66 66 */ 67 - struct afs_addr_list *afs_parse_text_addrs(const char *text, size_t len, 68 - char delim, 69 - unsigned short service, 70 - unsigned short port) 67 + struct afs_vlserver_list *afs_parse_text_addrs(struct afs_net *net, 68 + const char *text, size_t len, 69 + char delim, 70 + unsigned short service, 71 + unsigned short port) 71 72 { 73 + struct afs_vlserver_list *vllist; 72 74 struct afs_addr_list *alist; 73 75 const char *p, *end = text + len; 76 + const char *problem; 74 77 unsigned int nr = 0; 78 + int ret = -ENOMEM; 75 79 76 80 _enter("%*.*s,%c", (int)len, (int)len, text, delim); 77 81 78 - if (!len) 82 + if (!len) { 83 + _leave(" = -EDESTADDRREQ [empty]"); 79 84 return ERR_PTR(-EDESTADDRREQ); 85 + } 80 86 81 87 if (delim == ':' && (memchr(text, ',', len) || !memchr(text, '.', len))) 82 88 delim = ','; ··· 90 84 /* Count the addresses */ 91 85 p = text; 92 86 do { 93 - if (!*p) 94 - return ERR_PTR(-EINVAL); 87 + if (!*p) { 88 + problem = "nul"; 89 + goto inval; 90 + } 95 91 if (*p == delim) 96 92 continue; 97 93 nr++; 98 94 if (*p == '[') { 99 95 p++; 100 - if (p == end) 101 - return ERR_PTR(-EINVAL); 96 + if (p == end) { 97 + problem = "brace1"; 98 + goto inval; 99 + } 102 100 p = memchr(p, ']', end - p); 103 - if (!p) 104 - return ERR_PTR(-EINVAL); 101 + if (!p) { 102 + problem = "brace2"; 103 + goto inval; 104 + } 105 105 p++; 106 106 if (p >= end) 107 107 break; ··· 121 109 122 110 _debug("%u/%u addresses", nr, AFS_MAX_ADDRESSES); 123 111 124 - alist = afs_alloc_addrlist(nr, service, port); 125 - if (!alist) 112 + vllist = afs_alloc_vlserver_list(1); 113 + if (!vllist) 126 114 return ERR_PTR(-ENOMEM); 115 + 116 + vllist->nr_servers = 1; 117 + vllist->servers[0].server = afs_alloc_vlserver("<dummy>", 7, AFS_VL_PORT); 118 + if (!vllist->servers[0].server) 119 + goto error_vl; 120 + 121 + alist = afs_alloc_addrlist(nr, service, AFS_VL_PORT); 122 + if (!alist) 123 + goto error; 127 124 128 125 /* Extract the addresses */ 129 126 p = text; ··· 156 135 break; 157 136 } 158 137 159 - if (in4_pton(p, q - p, (u8 *)&x[0], -1, &stop)) 138 + if (in4_pton(p, q - p, (u8 *)&x[0], -1, &stop)) { 160 139 family = AF_INET; 161 - else if (in6_pton(p, q - p, (u8 *)x, -1, &stop)) 140 + } else if (in6_pton(p, q - p, (u8 *)x, -1, &stop)) { 162 141 family = AF_INET6; 163 - else 142 + } else { 143 + problem = "family"; 164 144 goto bad_address; 165 - 166 - if (stop != q) 167 - goto bad_address; 145 + } 168 146 169 147 p = q; 148 + if (stop != p) { 149 + problem = "nostop"; 150 + goto bad_address; 151 + } 152 + 170 153 if (q < end && *q == ']') 171 154 p++; 172 155 ··· 179 154 /* Port number specification "+1234" */ 180 155 xport = 0; 181 156 p++; 182 - if (p >= end || !isdigit(*p)) 157 + if (p >= end || !isdigit(*p)) { 158 + problem = "port"; 183 159 goto bad_address; 160 + } 184 161 do { 185 162 xport *= 10; 186 163 xport += *p - '0'; 187 - if (xport > 65535) 164 + if (xport > 65535) { 165 + problem = "pval"; 188 166 goto bad_address; 167 + } 189 168 p++; 190 169 } while (p < end && isdigit(*p)); 191 170 } else if (*p == delim) { 192 171 p++; 193 172 } else { 173 + problem = "weird"; 194 174 goto bad_address; 195 175 } 196 176 } ··· 207 177 208 178 } while (p < end); 209 179 180 + rcu_assign_pointer(vllist->servers[0].server->addresses, alist); 210 181 _leave(" = [nr %u]", alist->nr_addrs); 211 - return alist; 182 + return vllist; 212 183 213 - bad_address: 214 - kfree(alist); 184 + inval: 185 + _leave(" = -EINVAL [%s %zu %*.*s]", 186 + problem, p - text, (int)len, (int)len, text); 215 187 return ERR_PTR(-EINVAL); 188 + bad_address: 189 + _leave(" = -EINVAL [%s %zu %*.*s]", 190 + problem, p - text, (int)len, (int)len, text); 191 + ret = -EINVAL; 192 + error: 193 + afs_put_addrlist(alist); 194 + error_vl: 195 + afs_put_vlserverlist(net, vllist); 196 + return ERR_PTR(ret); 216 197 } 217 198 218 199 /* ··· 242 201 /* 243 202 * Perform a DNS query for VL servers and build a up an address list. 244 203 */ 245 - struct afs_addr_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry) 204 + struct afs_vlserver_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry) 246 205 { 247 - struct afs_addr_list *alist; 248 - char *vllist = NULL; 206 + struct afs_vlserver_list *vllist; 207 + char *result = NULL; 249 208 int ret; 250 209 251 210 _enter("%s", cell->name); 252 211 253 - ret = dns_query("afsdb", cell->name, cell->name_len, 254 - "", &vllist, _expiry); 255 - if (ret < 0) 212 + ret = dns_query("afsdb", cell->name, cell->name_len, "srv=1", 213 + &result, _expiry); 214 + if (ret < 0) { 215 + _leave(" = %d [dns]", ret); 256 216 return ERR_PTR(ret); 257 - 258 - alist = afs_parse_text_addrs(vllist, strlen(vllist), ',', 259 - VL_SERVICE, AFS_VL_PORT); 260 - if (IS_ERR(alist)) { 261 - kfree(vllist); 262 - if (alist != ERR_PTR(-ENOMEM)) 263 - pr_err("Failed to parse DNS data\n"); 264 - return alist; 265 217 } 266 218 267 - kfree(vllist); 268 - return alist; 219 + if (*_expiry == 0) 220 + *_expiry = ktime_get_real_seconds() + 60; 221 + 222 + if (ret > 1 && result[0] == 0) 223 + vllist = afs_extract_vlserver_list(cell, result, ret); 224 + else 225 + vllist = afs_parse_text_addrs(cell->net, result, ret, ',', 226 + VL_SERVICE, AFS_VL_PORT); 227 + kfree(result); 228 + if (IS_ERR(vllist) && vllist != ERR_PTR(-ENOMEM)) 229 + pr_err("Failed to parse DNS data %ld\n", PTR_ERR(vllist)); 230 + 231 + return vllist; 269 232 } 270 233 271 234 /* ··· 303 258 sizeof(alist->addrs[0]) * (alist->nr_addrs - i)); 304 259 305 260 srx = &alist->addrs[i]; 261 + srx->srx_family = AF_RXRPC; 262 + srx->transport_type = SOCK_DGRAM; 306 263 srx->transport_len = sizeof(srx->transport.sin); 307 264 srx->transport.sin.sin_family = AF_INET; 308 265 srx->transport.sin.sin_port = htons(port); ··· 343 296 sizeof(alist->addrs[0]) * (alist->nr_addrs - i)); 344 297 345 298 srx = &alist->addrs[i]; 299 + srx->srx_family = AF_RXRPC; 300 + srx->transport_type = SOCK_DGRAM; 346 301 srx->transport_len = sizeof(srx->transport.sin6); 347 302 srx->transport.sin6.sin6_family = AF_INET6; 348 303 srx->transport.sin6.sin6_port = htons(port); ··· 357 308 */ 358 309 bool afs_iterate_addresses(struct afs_addr_cursor *ac) 359 310 { 360 - _enter("%hu+%hd", ac->start, (short)ac->index); 311 + unsigned long set, failed; 312 + int index; 361 313 362 314 if (!ac->alist) 363 315 return false; 364 316 365 - if (ac->begun) { 366 - ac->index++; 367 - if (ac->index == ac->alist->nr_addrs) 368 - ac->index = 0; 317 + set = ac->alist->responded; 318 + failed = ac->alist->failed; 319 + _enter("%lx-%lx-%lx,%d", set, failed, ac->tried, ac->index); 369 320 370 - if (ac->index == ac->start) { 371 - ac->error = -EDESTADDRREQ; 372 - return false; 373 - } 374 - } 321 + ac->nr_iterations++; 375 322 376 - ac->begun = true; 323 + set &= ~(failed | ac->tried); 324 + 325 + if (!set) 326 + return false; 327 + 328 + index = READ_ONCE(ac->alist->preferred); 329 + if (test_bit(index, &set)) 330 + goto selected; 331 + 332 + index = __ffs(set); 333 + 334 + selected: 335 + ac->index = index; 336 + set_bit(index, &ac->tried); 377 337 ac->responded = false; 378 - ac->addr = &ac->alist->addrs[ac->index]; 379 338 return true; 380 339 } 381 340 ··· 396 339 397 340 alist = ac->alist; 398 341 if (alist) { 399 - if (ac->responded && ac->index != ac->start) 400 - WRITE_ONCE(alist->index, ac->index); 342 + if (ac->responded && 343 + ac->index != alist->preferred && 344 + test_bit(ac->alist->preferred, &ac->tried)) 345 + WRITE_ONCE(alist->preferred, ac->index); 401 346 afs_put_addrlist(alist); 347 + ac->alist = NULL; 402 348 } 403 349 404 - ac->addr = NULL; 405 - ac->alist = NULL; 406 - ac->begun = false; 407 350 return ac->error; 408 - } 409 - 410 - /* 411 - * Set the address cursor for iterating over VL servers. 412 - */ 413 - int afs_set_vl_cursor(struct afs_addr_cursor *ac, struct afs_cell *cell) 414 - { 415 - struct afs_addr_list *alist; 416 - int ret; 417 - 418 - if (!rcu_access_pointer(cell->vl_addrs)) { 419 - ret = wait_on_bit(&cell->flags, AFS_CELL_FL_NO_LOOKUP_YET, 420 - TASK_INTERRUPTIBLE); 421 - if (ret < 0) 422 - return ret; 423 - 424 - if (!rcu_access_pointer(cell->vl_addrs) && 425 - ktime_get_real_seconds() < cell->dns_expiry) 426 - return cell->error; 427 - } 428 - 429 - read_lock(&cell->vl_addrs_lock); 430 - alist = rcu_dereference_protected(cell->vl_addrs, 431 - lockdep_is_held(&cell->vl_addrs_lock)); 432 - if (alist->nr_addrs > 0) 433 - afs_get_addrlist(alist); 434 - else 435 - alist = NULL; 436 - read_unlock(&cell->vl_addrs_lock); 437 - 438 - if (!alist) 439 - return -EDESTADDRREQ; 440 - 441 - ac->alist = alist; 442 - ac->addr = NULL; 443 - ac->start = READ_ONCE(alist->index); 444 - ac->index = ac->start; 445 - ac->error = 0; 446 - ac->begun = false; 447 - return 0; 448 351 }
+26 -24
fs/afs/afs.h
··· 23 23 #define AFSPATHMAX 1024 /* Maximum length of a pathname plus NUL */ 24 24 #define AFSOPAQUEMAX 1024 /* Maximum length of an opaque field */ 25 25 26 - typedef unsigned afs_volid_t; 27 - typedef unsigned afs_vnodeid_t; 28 - typedef unsigned long long afs_dataversion_t; 26 + typedef u64 afs_volid_t; 27 + typedef u64 afs_vnodeid_t; 28 + typedef u64 afs_dataversion_t; 29 29 30 30 typedef enum { 31 31 AFSVL_RWVOL, /* read/write volume */ ··· 52 52 */ 53 53 struct afs_fid { 54 54 afs_volid_t vid; /* volume ID */ 55 - afs_vnodeid_t vnode; /* file index within volume */ 56 - unsigned unique; /* unique ID number (file index version) */ 55 + afs_vnodeid_t vnode; /* Lower 64-bits of file index within volume */ 56 + u32 vnode_hi; /* Upper 32-bits of file index */ 57 + u32 unique; /* unique ID number (file index version) */ 57 58 }; 58 59 59 60 /* ··· 68 67 } afs_callback_type_t; 69 68 70 69 struct afs_callback { 70 + time64_t expires_at; /* Time at which expires */ 71 71 unsigned version; /* Callback version */ 72 - unsigned expiry; /* Time at which expires */ 73 72 afs_callback_type_t type; /* Type of callback */ 74 73 }; 75 74 76 75 struct afs_callback_break { 77 76 struct afs_fid fid; /* File identifier */ 78 - struct afs_callback cb; /* Callback details */ 77 + //struct afs_callback cb; /* Callback details */ 79 78 }; 80 79 81 80 #define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */ ··· 130 129 struct afs_file_status { 131 130 u64 size; /* file size */ 132 131 afs_dataversion_t data_version; /* current data version */ 133 - time_t mtime_client; /* last time client changed data */ 134 - time_t mtime_server; /* last time server changed data */ 135 - unsigned abort_code; /* Abort if bulk-fetching this failed */ 136 - 137 - afs_file_type_t type; /* file type */ 138 - unsigned nlink; /* link count */ 139 - u32 author; /* author ID */ 140 - u32 owner; /* owner ID */ 141 - u32 group; /* group ID */ 132 + struct timespec64 mtime_client; /* Last time client changed data */ 133 + struct timespec64 mtime_server; /* Last time server changed data */ 134 + s64 author; /* author ID */ 135 + s64 owner; /* owner ID */ 136 + s64 group; /* group ID */ 142 137 afs_access_t caller_access; /* access rights for authenticated caller */ 143 138 afs_access_t anon_access; /* access rights for unauthenticated caller */ 144 139 umode_t mode; /* UNIX mode */ 140 + afs_file_type_t type; /* file type */ 141 + u32 nlink; /* link count */ 145 142 s32 lock_count; /* file lock count (0=UNLK -1=WRLCK +ve=#RDLCK */ 143 + u32 abort_code; /* Abort if bulk-fetching this failed */ 146 144 }; 147 145 148 146 /* ··· 158 158 * AFS volume synchronisation information 159 159 */ 160 160 struct afs_volsync { 161 - time_t creation; /* volume creation time */ 161 + time64_t creation; /* volume creation time */ 162 162 }; 163 163 164 164 /* 165 165 * AFS volume status record 166 166 */ 167 167 struct afs_volume_status { 168 - u32 vid; /* volume ID */ 169 - u32 parent_id; /* parent volume ID */ 168 + afs_volid_t vid; /* volume ID */ 169 + afs_volid_t parent_id; /* parent volume ID */ 170 170 u8 online; /* true if volume currently online and available */ 171 171 u8 in_service; /* true if volume currently in service */ 172 172 u8 blessed; /* same as in_service */ 173 173 u8 needs_salvage; /* true if consistency checking required */ 174 174 u32 type; /* volume type (afs_voltype_t) */ 175 - u32 min_quota; /* minimum space set aside (blocks) */ 176 - u32 max_quota; /* maximum space this volume may occupy (blocks) */ 177 - u32 blocks_in_use; /* space this volume currently occupies (blocks) */ 178 - u32 part_blocks_avail; /* space available in volume's partition */ 179 - u32 part_max_blocks; /* size of volume's partition */ 175 + u64 min_quota; /* minimum space set aside (blocks) */ 176 + u64 max_quota; /* maximum space this volume may occupy (blocks) */ 177 + u64 blocks_in_use; /* space this volume currently occupies (blocks) */ 178 + u64 part_blocks_avail; /* space available in volume's partition */ 179 + u64 part_max_blocks; /* size of volume's partition */ 180 + s64 vol_copy_date; 181 + s64 vol_backup_date; 180 182 }; 181 183 182 184 #define AFS_BLOCK_SIZE 1024
+1 -1
fs/afs/cache.c
··· 49 49 struct afs_vnode *vnode = cookie_netfs_data; 50 50 struct afs_vnode_cache_aux aux; 51 51 52 - _enter("{%x,%x,%llx},%p,%u", 52 + _enter("{%llx,%x,%llx},%p,%u", 53 53 vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, 54 54 buffer, buflen); 55 55
+8 -9
fs/afs/callback.c
··· 210 210 /* 211 211 * actually break a callback 212 212 */ 213 - void afs_break_callback(struct afs_vnode *vnode) 213 + void __afs_break_callback(struct afs_vnode *vnode) 214 214 { 215 215 _enter(""); 216 - 217 - write_seqlock(&vnode->cb_lock); 218 216 219 217 clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 220 218 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { ··· 228 230 afs_lock_may_be_available(vnode); 229 231 spin_unlock(&vnode->lock); 230 232 } 233 + } 231 234 235 + void afs_break_callback(struct afs_vnode *vnode) 236 + { 237 + write_seqlock(&vnode->cb_lock); 238 + __afs_break_callback(vnode); 232 239 write_sequnlock(&vnode->cb_lock); 233 240 } 234 241 ··· 313 310 /* TODO: Sort the callback break list by volume ID */ 314 311 315 312 for (; count > 0; callbacks++, count--) { 316 - _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", 313 + _debug("- Fid { vl=%08llx n=%llu u=%u }", 317 314 callbacks->fid.vid, 318 315 callbacks->fid.vnode, 319 - callbacks->fid.unique, 320 - callbacks->cb.version, 321 - callbacks->cb.expiry, 322 - callbacks->cb.type 323 - ); 316 + callbacks->fid.unique); 324 317 afs_break_one_callback(server, &callbacks->fid); 325 318 } 326 319
+41 -22
fs/afs/cell.c
··· 20 20 #include "internal.h" 21 21 22 22 static unsigned __read_mostly afs_cell_gc_delay = 10; 23 + static unsigned __read_mostly afs_cell_min_ttl = 10 * 60; 24 + static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60; 23 25 24 26 static void afs_manage_cell(struct work_struct *); 25 27 ··· 121 119 */ 122 120 static struct afs_cell *afs_alloc_cell(struct afs_net *net, 123 121 const char *name, unsigned int namelen, 124 - const char *vllist) 122 + const char *addresses) 125 123 { 126 124 struct afs_cell *cell; 127 125 int i, ret; ··· 136 134 if (namelen == 5 && memcmp(name, "@cell", 5) == 0) 137 135 return ERR_PTR(-EINVAL); 138 136 139 - _enter("%*.*s,%s", namelen, namelen, name, vllist); 137 + _enter("%*.*s,%s", namelen, namelen, name, addresses); 140 138 141 139 cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL); 142 140 if (!cell) { ··· 155 153 (1 << AFS_CELL_FL_NO_LOOKUP_YET)); 156 154 INIT_LIST_HEAD(&cell->proc_volumes); 157 155 rwlock_init(&cell->proc_lock); 158 - rwlock_init(&cell->vl_addrs_lock); 156 + rwlock_init(&cell->vl_servers_lock); 159 157 160 158 /* Fill in the VL server list if we were given a list of addresses to 161 159 * use. 162 160 */ 163 - if (vllist) { 164 - struct afs_addr_list *alist; 161 + if (addresses) { 162 + struct afs_vlserver_list *vllist; 165 163 166 - alist = afs_parse_text_addrs(vllist, strlen(vllist), ':', 167 - VL_SERVICE, AFS_VL_PORT); 168 - if (IS_ERR(alist)) { 169 - ret = PTR_ERR(alist); 164 + vllist = afs_parse_text_addrs(net, 165 + addresses, strlen(addresses), ':', 166 + VL_SERVICE, AFS_VL_PORT); 167 + if (IS_ERR(vllist)) { 168 + ret = PTR_ERR(vllist); 170 169 goto parse_failed; 171 170 } 172 171 173 - rcu_assign_pointer(cell->vl_addrs, alist); 172 + rcu_assign_pointer(cell->vl_servers, vllist); 174 173 cell->dns_expiry = TIME64_MAX; 174 + } else { 175 + cell->dns_expiry = ktime_get_real_seconds(); 175 176 } 176 177 177 178 _leave(" = %p", cell); ··· 361 356 */ 362 357 static void afs_update_cell(struct afs_cell *cell) 363 358 { 364 - struct afs_addr_list *alist, *old; 365 - time64_t now, expiry; 359 + struct afs_vlserver_list *vllist, *old; 360 + unsigned int min_ttl = READ_ONCE(afs_cell_min_ttl); 361 + unsigned int max_ttl = READ_ONCE(afs_cell_max_ttl); 362 + time64_t now, expiry = 0; 366 363 367 364 _enter("%s", cell->name); 368 365 369 - alist = afs_dns_query(cell, &expiry); 370 - if (IS_ERR(alist)) { 371 - switch (PTR_ERR(alist)) { 366 + vllist = afs_dns_query(cell, &expiry); 367 + 368 + now = ktime_get_real_seconds(); 369 + if (min_ttl > max_ttl) 370 + max_ttl = min_ttl; 371 + if (expiry < now + min_ttl) 372 + expiry = now + min_ttl; 373 + else if (expiry > now + max_ttl) 374 + expiry = now + max_ttl; 375 + 376 + if (IS_ERR(vllist)) { 377 + switch (PTR_ERR(vllist)) { 372 378 case -ENODATA: 373 - /* The DNS said that the cell does not exist */ 379 + case -EDESTADDRREQ: 380 + /* The DNS said that the cell does not exist or there 381 + * weren't any addresses to be had. 382 + */ 374 383 set_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags); 375 384 clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags); 376 - cell->dns_expiry = ktime_get_real_seconds() + 61; 385 + cell->dns_expiry = expiry; 377 386 break; 378 387 379 388 case -EAGAIN: 380 389 case -ECONNREFUSED: 381 390 default: 382 391 set_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags); 383 - cell->dns_expiry = ktime_get_real_seconds() + 10; 392 + cell->dns_expiry = now + 10; 384 393 break; 385 394 } 386 395 ··· 406 387 /* Exclusion on changing vl_addrs is achieved by a 407 388 * non-reentrant work item. 408 389 */ 409 - old = rcu_dereference_protected(cell->vl_addrs, true); 410 - rcu_assign_pointer(cell->vl_addrs, alist); 390 + old = rcu_dereference_protected(cell->vl_servers, true); 391 + rcu_assign_pointer(cell->vl_servers, vllist); 411 392 cell->dns_expiry = expiry; 412 393 413 394 if (old) 414 - afs_put_addrlist(old); 395 + afs_put_vlserverlist(cell->net, old); 415 396 } 416 397 417 398 if (test_and_clear_bit(AFS_CELL_FL_NO_LOOKUP_YET, &cell->flags)) ··· 433 414 434 415 ASSERTCMP(atomic_read(&cell->usage), ==, 0); 435 416 436 - afs_put_addrlist(rcu_access_pointer(cell->vl_addrs)); 417 + afs_put_vlserverlist(cell->net, rcu_access_pointer(cell->vl_servers)); 437 418 key_put(cell->anonymous_key); 438 419 kfree(cell); 439 420
+219 -68
fs/afs/cmservice.c
··· 16 16 #include <linux/ip.h> 17 17 #include "internal.h" 18 18 #include "afs_cm.h" 19 + #include "protocol_yfs.h" 19 20 20 21 static int afs_deliver_cb_init_call_back_state(struct afs_call *); 21 22 static int afs_deliver_cb_init_call_back_state3(struct afs_call *); ··· 30 29 static void SRXAFSCB_Probe(struct work_struct *); 31 30 static void SRXAFSCB_ProbeUuid(struct work_struct *); 32 31 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *); 32 + 33 + static int afs_deliver_yfs_cb_callback(struct afs_call *); 33 34 34 35 #define CM_NAME(name) \ 35 36 const char afs_SRXCB##name##_name[] __tracepoint_string = \ ··· 104 101 }; 105 102 106 103 /* 104 + * YFS CB.CallBack operation type 105 + */ 106 + static CM_NAME(YFS_CallBack); 107 + static const struct afs_call_type afs_SRXYFSCB_CallBack = { 108 + .name = afs_SRXCBYFS_CallBack_name, 109 + .deliver = afs_deliver_yfs_cb_callback, 110 + .destructor = afs_cm_destructor, 111 + .work = SRXAFSCB_CallBack, 112 + }; 113 + 114 + /* 107 115 * route an incoming cache manager call 108 116 * - return T if supported, F if not 109 117 */ 110 118 bool afs_cm_incoming_call(struct afs_call *call) 111 119 { 112 - _enter("{CB.OP %u}", call->operation_ID); 120 + _enter("{%u, CB.OP %u}", call->service_id, call->operation_ID); 121 + 122 + call->epoch = rxrpc_kernel_get_epoch(call->net->socket, call->rxcall); 113 123 114 124 switch (call->operation_ID) { 115 125 case CBCallBack: ··· 143 127 case CBTellMeAboutYourself: 144 128 call->type = &afs_SRXCBTellMeAboutYourself; 145 129 return true; 130 + case YFSCBCallBack: 131 + if (call->service_id != YFS_CM_SERVICE) 132 + return false; 133 + call->type = &afs_SRXYFSCB_CallBack; 134 + return true; 146 135 default: 147 136 return false; 148 137 } 138 + } 139 + 140 + /* 141 + * Record a probe to the cache manager from a server. 142 + */ 143 + static int afs_record_cm_probe(struct afs_call *call, struct afs_server *server) 144 + { 145 + _enter(""); 146 + 147 + if (test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags) && 148 + !test_bit(AFS_SERVER_FL_PROBING, &server->flags)) { 149 + if (server->cm_epoch == call->epoch) 150 + return 0; 151 + 152 + if (!server->probe.said_rebooted) { 153 + pr_notice("kAFS: FS rebooted %pU\n", &server->uuid); 154 + server->probe.said_rebooted = true; 155 + } 156 + } 157 + 158 + spin_lock(&server->probe_lock); 159 + 160 + if (!test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) { 161 + server->cm_epoch = call->epoch; 162 + server->probe.cm_epoch = call->epoch; 163 + goto out; 164 + } 165 + 166 + if (server->probe.cm_probed && 167 + call->epoch != server->probe.cm_epoch && 168 + !server->probe.said_inconsistent) { 169 + pr_notice("kAFS: FS endpoints inconsistent %pU\n", 170 + &server->uuid); 171 + server->probe.said_inconsistent = true; 172 + } 173 + 174 + if (!server->probe.cm_probed || call->epoch == server->cm_epoch) 175 + server->probe.cm_epoch = server->cm_epoch; 176 + 177 + out: 178 + server->probe.cm_probed = true; 179 + spin_unlock(&server->probe_lock); 180 + return 0; 181 + } 182 + 183 + /* 184 + * Find the server record by peer address and record a probe to the cache 185 + * manager from a server. 186 + */ 187 + static int afs_find_cm_server_by_peer(struct afs_call *call) 188 + { 189 + struct sockaddr_rxrpc srx; 190 + struct afs_server *server; 191 + 192 + rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 193 + 194 + server = afs_find_server(call->net, &srx); 195 + if (!server) { 196 + trace_afs_cm_no_server(call, &srx); 197 + return 0; 198 + } 199 + 200 + call->cm_server = server; 201 + return afs_record_cm_probe(call, server); 202 + } 203 + 204 + /* 205 + * Find the server record by server UUID and record a probe to the cache 206 + * manager from a server. 207 + */ 208 + static int afs_find_cm_server_by_uuid(struct afs_call *call, 209 + struct afs_uuid *uuid) 210 + { 211 + struct afs_server *server; 212 + 213 + rcu_read_lock(); 214 + server = afs_find_server_by_uuid(call->net, call->request); 215 + rcu_read_unlock(); 216 + if (!server) { 217 + trace_afs_cm_no_server_u(call, call->request); 218 + return 0; 219 + } 220 + 221 + call->cm_server = server; 222 + return afs_record_cm_probe(call, server); 149 223 } 150 224 151 225 /* ··· 274 168 static int afs_deliver_cb_callback(struct afs_call *call) 275 169 { 276 170 struct afs_callback_break *cb; 277 - struct sockaddr_rxrpc srx; 278 171 __be32 *bp; 279 172 int ret, loop; 280 173 ··· 281 176 282 177 switch (call->unmarshall) { 283 178 case 0: 284 - call->offset = 0; 179 + afs_extract_to_tmp(call); 285 180 call->unmarshall++; 286 181 287 182 /* extract the FID array and its count in two steps */ 288 183 case 1: 289 184 _debug("extract FID count"); 290 - ret = afs_extract_data(call, &call->tmp, 4, true); 185 + ret = afs_extract_data(call, true); 291 186 if (ret < 0) 292 187 return ret; 293 188 294 189 call->count = ntohl(call->tmp); 295 190 _debug("FID count: %u", call->count); 296 191 if (call->count > AFSCBMAX) 297 - return afs_protocol_error(call, -EBADMSG); 192 + return afs_protocol_error(call, -EBADMSG, 193 + afs_eproto_cb_fid_count); 298 194 299 195 call->buffer = kmalloc(array3_size(call->count, 3, 4), 300 196 GFP_KERNEL); 301 197 if (!call->buffer) 302 198 return -ENOMEM; 303 - call->offset = 0; 199 + afs_extract_to_buf(call, call->count * 3 * 4); 304 200 call->unmarshall++; 305 201 306 202 case 2: 307 203 _debug("extract FID array"); 308 - ret = afs_extract_data(call, call->buffer, 309 - call->count * 3 * 4, true); 204 + ret = afs_extract_data(call, true); 310 205 if (ret < 0) 311 206 return ret; 312 207 ··· 323 218 cb->fid.vid = ntohl(*bp++); 324 219 cb->fid.vnode = ntohl(*bp++); 325 220 cb->fid.unique = ntohl(*bp++); 326 - cb->cb.type = AFSCM_CB_UNTYPED; 327 221 } 328 222 329 - call->offset = 0; 223 + afs_extract_to_tmp(call); 330 224 call->unmarshall++; 331 225 332 226 /* extract the callback array and its count in two steps */ 333 227 case 3: 334 228 _debug("extract CB count"); 335 - ret = afs_extract_data(call, &call->tmp, 4, true); 229 + ret = afs_extract_data(call, true); 336 230 if (ret < 0) 337 231 return ret; 338 232 339 233 call->count2 = ntohl(call->tmp); 340 234 _debug("CB count: %u", call->count2); 341 235 if (call->count2 != call->count && call->count2 != 0) 342 - return afs_protocol_error(call, -EBADMSG); 343 - call->offset = 0; 236 + return afs_protocol_error(call, -EBADMSG, 237 + afs_eproto_cb_count); 238 + call->_iter = &call->iter; 239 + iov_iter_discard(&call->iter, READ, call->count2 * 3 * 4); 344 240 call->unmarshall++; 345 241 346 242 case 4: 347 - _debug("extract CB array"); 348 - ret = afs_extract_data(call, call->buffer, 349 - call->count2 * 3 * 4, false); 243 + _debug("extract discard %zu/%u", 244 + iov_iter_count(&call->iter), call->count2 * 3 * 4); 245 + 246 + ret = afs_extract_data(call, false); 350 247 if (ret < 0) 351 248 return ret; 352 249 353 - _debug("unmarshall CB array"); 354 - cb = call->request; 355 - bp = call->buffer; 356 - for (loop = call->count2; loop > 0; loop--, cb++) { 357 - cb->cb.version = ntohl(*bp++); 358 - cb->cb.expiry = ntohl(*bp++); 359 - cb->cb.type = ntohl(*bp++); 360 - } 361 - 362 - call->offset = 0; 363 250 call->unmarshall++; 364 251 case 5: 365 252 break; 366 253 } 367 254 368 255 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 369 - return -EIO; 256 + return afs_io_error(call, afs_io_error_cm_reply); 370 257 371 258 /* we'll need the file server record as that tells us which set of 372 259 * vnodes to operate upon */ 373 - rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 374 - call->cm_server = afs_find_server(call->net, &srx); 375 - if (!call->cm_server) 376 - trace_afs_cm_no_server(call, &srx); 377 - 378 - return afs_queue_call_work(call); 260 + return afs_find_cm_server_by_peer(call); 379 261 } 380 262 381 263 /* ··· 386 294 */ 387 295 static int afs_deliver_cb_init_call_back_state(struct afs_call *call) 388 296 { 389 - struct sockaddr_rxrpc srx; 390 297 int ret; 391 298 392 299 _enter(""); 393 300 394 - rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 395 - 396 - ret = afs_extract_data(call, NULL, 0, false); 301 + afs_extract_discard(call, 0); 302 + ret = afs_extract_data(call, false); 397 303 if (ret < 0) 398 304 return ret; 399 305 400 306 /* we'll need the file server record as that tells us which set of 401 307 * vnodes to operate upon */ 402 - call->cm_server = afs_find_server(call->net, &srx); 403 - if (!call->cm_server) 404 - trace_afs_cm_no_server(call, &srx); 405 - 406 - return afs_queue_call_work(call); 308 + return afs_find_cm_server_by_peer(call); 407 309 } 408 310 409 311 /* ··· 416 330 417 331 switch (call->unmarshall) { 418 332 case 0: 419 - call->offset = 0; 420 333 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); 421 334 if (!call->buffer) 422 335 return -ENOMEM; 336 + afs_extract_to_buf(call, 11 * sizeof(__be32)); 423 337 call->unmarshall++; 424 338 425 339 case 1: 426 340 _debug("extract UUID"); 427 - ret = afs_extract_data(call, call->buffer, 428 - 11 * sizeof(__be32), false); 341 + ret = afs_extract_data(call, false); 429 342 switch (ret) { 430 343 case 0: break; 431 344 case -EAGAIN: return 0; ··· 447 362 for (loop = 0; loop < 6; loop++) 448 363 r->node[loop] = ntohl(b[loop + 5]); 449 364 450 - call->offset = 0; 451 365 call->unmarshall++; 452 366 453 367 case 2: ··· 454 370 } 455 371 456 372 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 457 - return -EIO; 373 + return afs_io_error(call, afs_io_error_cm_reply); 458 374 459 375 /* we'll need the file server record as that tells us which set of 460 376 * vnodes to operate upon */ 461 - rcu_read_lock(); 462 - call->cm_server = afs_find_server_by_uuid(call->net, call->request); 463 - rcu_read_unlock(); 464 - if (!call->cm_server) 465 - trace_afs_cm_no_server_u(call, call->request); 466 - 467 - return afs_queue_call_work(call); 377 + return afs_find_cm_server_by_uuid(call, call->request); 468 378 } 469 379 470 380 /* ··· 483 405 484 406 _enter(""); 485 407 486 - ret = afs_extract_data(call, NULL, 0, false); 408 + afs_extract_discard(call, 0); 409 + ret = afs_extract_data(call, false); 487 410 if (ret < 0) 488 411 return ret; 489 412 490 413 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 491 - return -EIO; 492 - 493 - return afs_queue_call_work(call); 414 + return afs_io_error(call, afs_io_error_cm_reply); 415 + return afs_find_cm_server_by_peer(call); 494 416 } 495 417 496 418 /* ··· 531 453 532 454 switch (call->unmarshall) { 533 455 case 0: 534 - call->offset = 0; 535 456 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); 536 457 if (!call->buffer) 537 458 return -ENOMEM; 459 + afs_extract_to_buf(call, 11 * sizeof(__be32)); 538 460 call->unmarshall++; 539 461 540 462 case 1: 541 463 _debug("extract UUID"); 542 - ret = afs_extract_data(call, call->buffer, 543 - 11 * sizeof(__be32), false); 464 + ret = afs_extract_data(call, false); 544 465 switch (ret) { 545 466 case 0: break; 546 467 case -EAGAIN: return 0; ··· 562 485 for (loop = 0; loop < 6; loop++) 563 486 r->node[loop] = ntohl(b[loop + 5]); 564 487 565 - call->offset = 0; 566 488 call->unmarshall++; 567 489 568 490 case 2: ··· 569 493 } 570 494 571 495 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 572 - return -EIO; 573 - 574 - return afs_queue_call_work(call); 496 + return afs_io_error(call, afs_io_error_cm_reply); 497 + return afs_find_cm_server_by_uuid(call, call->request); 575 498 } 576 499 577 500 /* ··· 645 570 646 571 _enter(""); 647 572 648 - ret = afs_extract_data(call, NULL, 0, false); 573 + afs_extract_discard(call, 0); 574 + ret = afs_extract_data(call, false); 649 575 if (ret < 0) 650 576 return ret; 651 577 652 578 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 653 - return -EIO; 579 + return afs_io_error(call, afs_io_error_cm_reply); 580 + return afs_find_cm_server_by_peer(call); 581 + } 654 582 655 - return afs_queue_call_work(call); 583 + /* 584 + * deliver request data to a YFS CB.CallBack call 585 + */ 586 + static int afs_deliver_yfs_cb_callback(struct afs_call *call) 587 + { 588 + struct afs_callback_break *cb; 589 + struct yfs_xdr_YFSFid *bp; 590 + size_t size; 591 + int ret, loop; 592 + 593 + _enter("{%u}", call->unmarshall); 594 + 595 + switch (call->unmarshall) { 596 + case 0: 597 + afs_extract_to_tmp(call); 598 + call->unmarshall++; 599 + 600 + /* extract the FID array and its count in two steps */ 601 + case 1: 602 + _debug("extract FID count"); 603 + ret = afs_extract_data(call, true); 604 + if (ret < 0) 605 + return ret; 606 + 607 + call->count = ntohl(call->tmp); 608 + _debug("FID count: %u", call->count); 609 + if (call->count > YFSCBMAX) 610 + return afs_protocol_error(call, -EBADMSG, 611 + afs_eproto_cb_fid_count); 612 + 613 + size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid)); 614 + call->buffer = kmalloc(size, GFP_KERNEL); 615 + if (!call->buffer) 616 + return -ENOMEM; 617 + afs_extract_to_buf(call, size); 618 + call->unmarshall++; 619 + 620 + case 2: 621 + _debug("extract FID array"); 622 + ret = afs_extract_data(call, false); 623 + if (ret < 0) 624 + return ret; 625 + 626 + _debug("unmarshall FID array"); 627 + call->request = kcalloc(call->count, 628 + sizeof(struct afs_callback_break), 629 + GFP_KERNEL); 630 + if (!call->request) 631 + return -ENOMEM; 632 + 633 + cb = call->request; 634 + bp = call->buffer; 635 + for (loop = call->count; loop > 0; loop--, cb++) { 636 + cb->fid.vid = xdr_to_u64(bp->volume); 637 + cb->fid.vnode = xdr_to_u64(bp->vnode.lo); 638 + cb->fid.vnode_hi = ntohl(bp->vnode.hi); 639 + cb->fid.unique = ntohl(bp->vnode.unique); 640 + bp++; 641 + } 642 + 643 + afs_extract_to_tmp(call); 644 + call->unmarshall++; 645 + 646 + case 3: 647 + break; 648 + } 649 + 650 + if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 651 + return afs_io_error(call, afs_io_error_cm_reply); 652 + 653 + /* We'll need the file server record as that tells us which set of 654 + * vnodes to operate upon. 655 + */ 656 + return afs_find_cm_server_by_peer(call); 656 657 }
+51 -24
fs/afs/dir.c
··· 138 138 ntohs(dbuf->blocks[tmp].hdr.magic)); 139 139 trace_afs_dir_check_failed(dvnode, off, i_size); 140 140 kunmap(page); 141 + trace_afs_file_error(dvnode, -EIO, afs_file_error_dir_bad_magic); 141 142 goto error; 142 143 } 143 144 ··· 191 190 retry: 192 191 i_size = i_size_read(&dvnode->vfs_inode); 193 192 if (i_size < 2048) 194 - return ERR_PTR(-EIO); 195 - if (i_size > 2048 * 1024) 193 + return ERR_PTR(afs_bad(dvnode, afs_file_error_dir_small)); 194 + if (i_size > 2048 * 1024) { 195 + trace_afs_file_error(dvnode, -EFBIG, afs_file_error_dir_big); 196 196 return ERR_PTR(-EFBIG); 197 + } 197 198 198 199 _enter("%llu", i_size); 199 200 ··· 318 315 /* 319 316 * deal with one block in an AFS directory 320 317 */ 321 - static int afs_dir_iterate_block(struct dir_context *ctx, 318 + static int afs_dir_iterate_block(struct afs_vnode *dvnode, 319 + struct dir_context *ctx, 322 320 union afs_xdr_dir_block *block, 323 321 unsigned blkoff) 324 322 { ··· 369 365 " (len %u/%zu)", 370 366 blkoff / sizeof(union afs_xdr_dir_block), 371 367 offset, next, tmp, nlen); 372 - return -EIO; 368 + return afs_bad(dvnode, afs_file_error_dir_over_end); 373 369 } 374 370 if (!(block->hdr.bitmap[next / 8] & 375 371 (1 << (next % 8)))) { ··· 377 373 " %u unmarked extension (len %u/%zu)", 378 374 blkoff / sizeof(union afs_xdr_dir_block), 379 375 offset, next, tmp, nlen); 380 - return -EIO; 376 + return afs_bad(dvnode, afs_file_error_dir_unmarked_ext); 381 377 } 382 378 383 379 _debug("ENT[%zu.%u]: ext %u/%zu", ··· 446 442 */ 447 443 page = req->pages[blkoff / PAGE_SIZE]; 448 444 if (!page) { 449 - ret = -EIO; 445 + ret = afs_bad(dvnode, afs_file_error_dir_missing_page); 450 446 break; 451 447 } 452 448 mark_page_accessed(page); ··· 459 455 do { 460 456 dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) / 461 457 sizeof(union afs_xdr_dir_block)]; 462 - ret = afs_dir_iterate_block(ctx, dblock, blkoff); 458 + ret = afs_dir_iterate_block(dvnode, ctx, dblock, blkoff); 463 459 if (ret != 1) { 464 460 kunmap(page); 465 461 goto out; ··· 552 548 } 553 549 554 550 *fid = cookie.fid; 555 - _leave(" = 0 { vn=%u u=%u }", fid->vnode, fid->unique); 551 + _leave(" = 0 { vn=%llu u=%u }", fid->vnode, fid->unique); 556 552 return 0; 557 553 } 558 554 ··· 830 826 struct key *key; 831 827 int ret; 832 828 833 - _enter("{%x:%u},%p{%pd},", 829 + _enter("{%llx:%llu},%p{%pd},", 834 830 dvnode->fid.vid, dvnode->fid.vnode, dentry, dentry); 835 831 836 832 ASSERTCMP(d_inode(dentry), ==, NULL); ··· 900 896 901 897 if (d_really_is_positive(dentry)) { 902 898 vnode = AFS_FS_I(d_inode(dentry)); 903 - _enter("{v={%x:%u} n=%pd fl=%lx},", 899 + _enter("{v={%llx:%llu} n=%pd fl=%lx},", 904 900 vnode->fid.vid, vnode->fid.vnode, dentry, 905 901 vnode->flags); 906 902 } else { ··· 969 965 /* if the vnode ID has changed, then the dirent points to a 970 966 * different file */ 971 967 if (fid.vnode != vnode->fid.vnode) { 972 - _debug("%pd: dirent changed [%u != %u]", 968 + _debug("%pd: dirent changed [%llu != %llu]", 973 969 dentry, fid.vnode, 974 970 vnode->fid.vnode); 975 971 goto not_found; ··· 1089 1085 1090 1086 vnode = AFS_FS_I(inode); 1091 1087 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 1088 + afs_vnode_commit_status(fc, vnode, 0); 1092 1089 d_add(new_dentry, inode); 1093 1090 } 1094 1091 ··· 1109 1104 1110 1105 mode |= S_IFDIR; 1111 1106 1112 - _enter("{%x:%u},{%pd},%ho", 1107 + _enter("{%llx:%llu},{%pd},%ho", 1113 1108 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode); 1114 1109 1115 1110 key = afs_request_key(dvnode->volume->cell); ··· 1174 1169 static int afs_rmdir(struct inode *dir, struct dentry *dentry) 1175 1170 { 1176 1171 struct afs_fs_cursor fc; 1177 - struct afs_vnode *dvnode = AFS_FS_I(dir); 1172 + struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; 1178 1173 struct key *key; 1179 1174 u64 data_version = dvnode->status.data_version; 1180 1175 int ret; 1181 1176 1182 - _enter("{%x:%u},{%pd}", 1177 + _enter("{%llx:%llu},{%pd}", 1183 1178 dvnode->fid.vid, dvnode->fid.vnode, dentry); 1184 1179 1185 1180 key = afs_request_key(dvnode->volume->cell); ··· 1188 1183 goto error; 1189 1184 } 1190 1185 1186 + /* Try to make sure we have a callback promise on the victim. */ 1187 + if (d_really_is_positive(dentry)) { 1188 + vnode = AFS_FS_I(d_inode(dentry)); 1189 + ret = afs_validate(vnode, key); 1190 + if (ret < 0) 1191 + goto error_key; 1192 + } 1193 + 1191 1194 ret = -ERESTARTSYS; 1192 1195 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1193 1196 while (afs_select_fileserver(&fc)) { 1194 1197 fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1195 - afs_fs_remove(&fc, dentry->d_name.name, true, 1198 + afs_fs_remove(&fc, vnode, dentry->d_name.name, true, 1196 1199 data_version); 1197 1200 } 1198 1201 ··· 1214 1201 } 1215 1202 } 1216 1203 1204 + error_key: 1217 1205 key_put(key); 1218 1206 error: 1219 1207 return ret; ··· 1245 1231 if (d_really_is_positive(dentry)) { 1246 1232 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); 1247 1233 1248 - if (dir_valid) { 1234 + if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 1235 + /* Already done */ 1236 + } else if (dir_valid) { 1249 1237 drop_nlink(&vnode->vfs_inode); 1250 1238 if (vnode->vfs_inode.i_nlink == 0) { 1251 1239 set_bit(AFS_VNODE_DELETED, &vnode->flags); ··· 1276 1260 static int afs_unlink(struct inode *dir, struct dentry *dentry) 1277 1261 { 1278 1262 struct afs_fs_cursor fc; 1279 - struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; 1263 + struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; 1280 1264 struct key *key; 1281 1265 unsigned long d_version = (unsigned long)dentry->d_fsdata; 1282 1266 u64 data_version = dvnode->status.data_version; 1283 1267 int ret; 1284 1268 1285 - _enter("{%x:%u},{%pd}", 1269 + _enter("{%llx:%llu},{%pd}", 1286 1270 dvnode->fid.vid, dvnode->fid.vnode, dentry); 1287 1271 1288 1272 if (dentry->d_name.len >= AFSNAMEMAX) ··· 1306 1290 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1307 1291 while (afs_select_fileserver(&fc)) { 1308 1292 fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1309 - afs_fs_remove(&fc, dentry->d_name.name, false, 1293 + 1294 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) && 1295 + !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) { 1296 + yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name, 1297 + data_version); 1298 + if (fc.ac.error != -ECONNABORTED || 1299 + fc.ac.abort_code != RXGEN_OPCODE) 1300 + continue; 1301 + set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags); 1302 + } 1303 + 1304 + afs_fs_remove(&fc, vnode, dentry->d_name.name, false, 1310 1305 data_version); 1311 1306 } 1312 1307 ··· 1357 1330 1358 1331 mode |= S_IFREG; 1359 1332 1360 - _enter("{%x:%u},{%pd},%ho,", 1333 + _enter("{%llx:%llu},{%pd},%ho,", 1361 1334 dvnode->fid.vid, dvnode->fid.vnode, dentry, mode); 1362 1335 1363 1336 ret = -ENAMETOOLONG; ··· 1420 1393 dvnode = AFS_FS_I(dir); 1421 1394 data_version = dvnode->status.data_version; 1422 1395 1423 - _enter("{%x:%u},{%x:%u},{%pd}", 1396 + _enter("{%llx:%llu},{%llx:%llu},{%pd}", 1424 1397 vnode->fid.vid, vnode->fid.vnode, 1425 1398 dvnode->fid.vid, dvnode->fid.vnode, 1426 1399 dentry); ··· 1491 1464 u64 data_version = dvnode->status.data_version; 1492 1465 int ret; 1493 1466 1494 - _enter("{%x:%u},{%pd},%s", 1467 + _enter("{%llx:%llu},{%pd},%s", 1495 1468 dvnode->fid.vid, dvnode->fid.vnode, dentry, 1496 1469 content); 1497 1470 ··· 1567 1540 orig_data_version = orig_dvnode->status.data_version; 1568 1541 new_data_version = new_dvnode->status.data_version; 1569 1542 1570 - _enter("{%x:%u},{%x:%u},{%x:%u},{%pd}", 1543 + _enter("{%llx:%llu},{%llx:%llu},{%llx:%llu},{%pd}", 1571 1544 orig_dvnode->fid.vid, orig_dvnode->fid.vnode, 1572 1545 vnode->fid.vid, vnode->fid.vnode, 1573 1546 new_dvnode->fid.vid, new_dvnode->fid.vnode, ··· 1634 1607 { 1635 1608 struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host); 1636 1609 1637 - _enter("{{%x:%u}[%lu]}", dvnode->fid.vid, dvnode->fid.vnode, page->index); 1610 + _enter("{{%llx:%llu}[%lu]}", dvnode->fid.vid, dvnode->fid.vnode, page->index); 1638 1611 1639 1612 set_page_private(page, 0); 1640 1613 ClearPagePrivate(page);
+2 -2
fs/afs/dynroot.c
··· 46 46 return 0; 47 47 } 48 48 49 - ret = dns_query("afsdb", name, len, "", NULL, NULL); 49 + ret = dns_query("afsdb", name, len, "srv=1", NULL, NULL); 50 50 if (ret == -ENODATA) 51 51 ret = -EDESTADDRREQ; 52 52 return ret; ··· 62 62 struct inode *inode; 63 63 int ret = -ENOENT; 64 64 65 - _enter("%p{%pd}, {%x:%u}", 65 + _enter("%p{%pd}, {%llx:%llu}", 66 66 dentry, dentry, vnode->fid.vid, vnode->fid.vnode); 67 67 68 68 if (!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
+4 -4
fs/afs/file.c
··· 121 121 struct key *key; 122 122 int ret; 123 123 124 - _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); 124 + _enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode); 125 125 126 126 key = afs_request_key(vnode->volume->cell); 127 127 if (IS_ERR(key)) { ··· 170 170 struct afs_vnode *vnode = AFS_FS_I(inode); 171 171 struct afs_file *af = file->private_data; 172 172 173 - _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); 173 + _enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode); 174 174 175 175 if ((file->f_mode & FMODE_WRITE)) 176 176 return vfs_fsync(file, 0); ··· 228 228 struct afs_fs_cursor fc; 229 229 int ret; 230 230 231 - _enter("%s{%x:%u.%u},%x,,,", 231 + _enter("%s{%llx:%llu.%u},%x,,,", 232 232 vnode->volume->name, 233 233 vnode->fid.vid, 234 234 vnode->fid.vnode, ··· 634 634 struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); 635 635 unsigned long priv; 636 636 637 - _enter("{{%x:%u}[%lu],%lx},%x", 637 + _enter("{{%llx:%llu}[%lu],%lx},%x", 638 638 vnode->fid.vid, vnode->fid.vnode, page->index, page->flags, 639 639 gfp_flags); 640 640
+11 -11
fs/afs/flock.c
··· 29 29 */ 30 30 void afs_lock_may_be_available(struct afs_vnode *vnode) 31 31 { 32 - _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 32 + _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 33 33 34 34 queue_delayed_work(afs_lock_manager, &vnode->lock_work, 0); 35 35 } ··· 76 76 struct afs_fs_cursor fc; 77 77 int ret; 78 78 79 - _enter("%s{%x:%u.%u},%x,%u", 79 + _enter("%s{%llx:%llu.%u},%x,%u", 80 80 vnode->volume->name, 81 81 vnode->fid.vid, 82 82 vnode->fid.vnode, ··· 107 107 struct afs_fs_cursor fc; 108 108 int ret; 109 109 110 - _enter("%s{%x:%u.%u},%x", 110 + _enter("%s{%llx:%llu.%u},%x", 111 111 vnode->volume->name, 112 112 vnode->fid.vid, 113 113 vnode->fid.vnode, ··· 138 138 struct afs_fs_cursor fc; 139 139 int ret; 140 140 141 - _enter("%s{%x:%u.%u},%x", 141 + _enter("%s{%llx:%llu.%u},%x", 142 142 vnode->volume->name, 143 143 vnode->fid.vid, 144 144 vnode->fid.vnode, ··· 175 175 struct key *key; 176 176 int ret; 177 177 178 - _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 178 + _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 179 179 180 180 spin_lock(&vnode->lock); 181 181 ··· 192 192 ret = afs_release_lock(vnode, vnode->lock_key); 193 193 if (ret < 0) 194 194 printk(KERN_WARNING "AFS:" 195 - " Failed to release lock on {%x:%x} error %d\n", 195 + " Failed to release lock on {%llx:%llx} error %d\n", 196 196 vnode->fid.vid, vnode->fid.vnode, ret); 197 197 198 198 spin_lock(&vnode->lock); ··· 229 229 key_put(key); 230 230 231 231 if (ret < 0) 232 - pr_warning("AFS: Failed to extend lock on {%x:%x} error %d\n", 232 + pr_warning("AFS: Failed to extend lock on {%llx:%llx} error %d\n", 233 233 vnode->fid.vid, vnode->fid.vnode, ret); 234 234 235 235 spin_lock(&vnode->lock); ··· 430 430 struct key *key = afs_file_key(file); 431 431 int ret; 432 432 433 - _enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); 433 + _enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); 434 434 435 435 /* only whole-file locks are supported */ 436 436 if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX) ··· 582 582 struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); 583 583 int ret; 584 584 585 - _enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); 585 + _enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); 586 586 587 587 /* Flush all pending writes before doing anything with locks. */ 588 588 vfs_fsync(file, 0); ··· 639 639 { 640 640 struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); 641 641 642 - _enter("{%x:%u},%d,{t=%x,fl=%x,r=%Ld:%Ld}", 642 + _enter("{%llx:%llu},%d,{t=%x,fl=%x,r=%Ld:%Ld}", 643 643 vnode->fid.vid, vnode->fid.vnode, cmd, 644 644 fl->fl_type, fl->fl_flags, 645 645 (long long) fl->fl_start, (long long) fl->fl_end); ··· 662 662 { 663 663 struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); 664 664 665 - _enter("{%x:%u},%d,{t=%x,fl=%x}", 665 + _enter("{%llx:%llu},%d,{t=%x,fl=%x}", 666 666 vnode->fid.vid, vnode->fid.vnode, cmd, 667 667 fl->fl_type, fl->fl_flags); 668 668
+270
fs/afs/fs_probe.c
··· 1 + /* AFS fileserver probing 2 + * 3 + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/sched.h> 13 + #include <linux/slab.h> 14 + #include "afs_fs.h" 15 + #include "internal.h" 16 + #include "protocol_yfs.h" 17 + 18 + static bool afs_fs_probe_done(struct afs_server *server) 19 + { 20 + if (!atomic_dec_and_test(&server->probe_outstanding)) 21 + return false; 22 + 23 + wake_up_var(&server->probe_outstanding); 24 + clear_bit_unlock(AFS_SERVER_FL_PROBING, &server->flags); 25 + wake_up_bit(&server->flags, AFS_SERVER_FL_PROBING); 26 + return true; 27 + } 28 + 29 + /* 30 + * Process the result of probing a fileserver. This is called after successful 31 + * or failed delivery of an FS.GetCapabilities operation. 32 + */ 33 + void afs_fileserver_probe_result(struct afs_call *call) 34 + { 35 + struct afs_addr_list *alist = call->alist; 36 + struct afs_server *server = call->reply[0]; 37 + unsigned int server_index = (long)call->reply[1]; 38 + unsigned int index = call->addr_ix; 39 + unsigned int rtt = UINT_MAX; 40 + bool have_result = false; 41 + u64 _rtt; 42 + int ret = call->error; 43 + 44 + _enter("%pU,%u", &server->uuid, index); 45 + 46 + spin_lock(&server->probe_lock); 47 + 48 + switch (ret) { 49 + case 0: 50 + server->probe.error = 0; 51 + goto responded; 52 + case -ECONNABORTED: 53 + if (!server->probe.responded) { 54 + server->probe.abort_code = call->abort_code; 55 + server->probe.error = ret; 56 + } 57 + goto responded; 58 + case -ENOMEM: 59 + case -ENONET: 60 + server->probe.local_failure = true; 61 + afs_io_error(call, afs_io_error_fs_probe_fail); 62 + goto out; 63 + case -ECONNRESET: /* Responded, but call expired. */ 64 + case -ENETUNREACH: 65 + case -EHOSTUNREACH: 66 + case -ECONNREFUSED: 67 + case -ETIMEDOUT: 68 + case -ETIME: 69 + default: 70 + clear_bit(index, &alist->responded); 71 + set_bit(index, &alist->failed); 72 + if (!server->probe.responded && 73 + (server->probe.error == 0 || 74 + server->probe.error == -ETIMEDOUT || 75 + server->probe.error == -ETIME)) 76 + server->probe.error = ret; 77 + afs_io_error(call, afs_io_error_fs_probe_fail); 78 + goto out; 79 + } 80 + 81 + responded: 82 + set_bit(index, &alist->responded); 83 + clear_bit(index, &alist->failed); 84 + 85 + if (call->service_id == YFS_FS_SERVICE) { 86 + server->probe.is_yfs = true; 87 + set_bit(AFS_SERVER_FL_IS_YFS, &server->flags); 88 + alist->addrs[index].srx_service = call->service_id; 89 + } else { 90 + server->probe.not_yfs = true; 91 + if (!server->probe.is_yfs) { 92 + clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags); 93 + alist->addrs[index].srx_service = call->service_id; 94 + } 95 + } 96 + 97 + /* Get the RTT and scale it to fit into a 32-bit value that represents 98 + * over a minute of time so that we can access it with one instruction 99 + * on a 32-bit system. 100 + */ 101 + _rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); 102 + _rtt /= 64; 103 + rtt = (_rtt > UINT_MAX) ? UINT_MAX : _rtt; 104 + if (rtt < server->probe.rtt) { 105 + server->probe.rtt = rtt; 106 + alist->preferred = index; 107 + have_result = true; 108 + } 109 + 110 + smp_wmb(); /* Set rtt before responded. */ 111 + server->probe.responded = true; 112 + set_bit(AFS_SERVER_FL_PROBED, &server->flags); 113 + out: 114 + spin_unlock(&server->probe_lock); 115 + 116 + _debug("probe [%u][%u] %pISpc rtt=%u ret=%d", 117 + server_index, index, &alist->addrs[index].transport, 118 + (unsigned int)rtt, ret); 119 + 120 + have_result |= afs_fs_probe_done(server); 121 + if (have_result) { 122 + server->probe.have_result = true; 123 + wake_up_var(&server->probe.have_result); 124 + wake_up_all(&server->probe_wq); 125 + } 126 + } 127 + 128 + /* 129 + * Probe all of a fileserver's addresses to find out the best route and to 130 + * query its capabilities. 131 + */ 132 + static int afs_do_probe_fileserver(struct afs_net *net, 133 + struct afs_server *server, 134 + struct key *key, 135 + unsigned int server_index) 136 + { 137 + struct afs_addr_cursor ac = { 138 + .index = 0, 139 + }; 140 + int ret; 141 + 142 + _enter("%pU", &server->uuid); 143 + 144 + read_lock(&server->fs_lock); 145 + ac.alist = rcu_dereference_protected(server->addresses, 146 + lockdep_is_held(&server->fs_lock)); 147 + read_unlock(&server->fs_lock); 148 + 149 + atomic_set(&server->probe_outstanding, ac.alist->nr_addrs); 150 + memset(&server->probe, 0, sizeof(server->probe)); 151 + server->probe.rtt = UINT_MAX; 152 + 153 + for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { 154 + ret = afs_fs_get_capabilities(net, server, &ac, key, server_index, 155 + true); 156 + if (ret != -EINPROGRESS) { 157 + afs_fs_probe_done(server); 158 + return ret; 159 + } 160 + } 161 + 162 + return 0; 163 + } 164 + 165 + /* 166 + * Send off probes to all unprobed servers. 167 + */ 168 + int afs_probe_fileservers(struct afs_net *net, struct key *key, 169 + struct afs_server_list *list) 170 + { 171 + struct afs_server *server; 172 + int i, ret; 173 + 174 + for (i = 0; i < list->nr_servers; i++) { 175 + server = list->servers[i].server; 176 + if (test_bit(AFS_SERVER_FL_PROBED, &server->flags)) 177 + continue; 178 + 179 + if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags)) { 180 + ret = afs_do_probe_fileserver(net, server, key, i); 181 + if (ret) 182 + return ret; 183 + } 184 + } 185 + 186 + return 0; 187 + } 188 + 189 + /* 190 + * Wait for the first as-yet untried fileserver to respond. 191 + */ 192 + int afs_wait_for_fs_probes(struct afs_server_list *slist, unsigned long untried) 193 + { 194 + struct wait_queue_entry *waits; 195 + struct afs_server *server; 196 + unsigned int rtt = UINT_MAX; 197 + bool have_responders = false; 198 + int pref = -1, i; 199 + 200 + _enter("%u,%lx", slist->nr_servers, untried); 201 + 202 + /* Only wait for servers that have a probe outstanding. */ 203 + for (i = 0; i < slist->nr_servers; i++) { 204 + if (test_bit(i, &untried)) { 205 + server = slist->servers[i].server; 206 + if (!test_bit(AFS_SERVER_FL_PROBING, &server->flags)) 207 + __clear_bit(i, &untried); 208 + if (server->probe.responded) 209 + have_responders = true; 210 + } 211 + } 212 + if (have_responders || !untried) 213 + return 0; 214 + 215 + waits = kmalloc(array_size(slist->nr_servers, sizeof(*waits)), GFP_KERNEL); 216 + if (!waits) 217 + return -ENOMEM; 218 + 219 + for (i = 0; i < slist->nr_servers; i++) { 220 + if (test_bit(i, &untried)) { 221 + server = slist->servers[i].server; 222 + init_waitqueue_entry(&waits[i], current); 223 + add_wait_queue(&server->probe_wq, &waits[i]); 224 + } 225 + } 226 + 227 + for (;;) { 228 + bool still_probing = false; 229 + 230 + set_current_state(TASK_INTERRUPTIBLE); 231 + for (i = 0; i < slist->nr_servers; i++) { 232 + if (test_bit(i, &untried)) { 233 + server = slist->servers[i].server; 234 + if (server->probe.responded) 235 + goto stop; 236 + if (test_bit(AFS_SERVER_FL_PROBING, &server->flags)) 237 + still_probing = true; 238 + } 239 + } 240 + 241 + if (!still_probing || unlikely(signal_pending(current))) 242 + goto stop; 243 + schedule(); 244 + } 245 + 246 + stop: 247 + set_current_state(TASK_RUNNING); 248 + 249 + for (i = 0; i < slist->nr_servers; i++) { 250 + if (test_bit(i, &untried)) { 251 + server = slist->servers[i].server; 252 + if (server->probe.responded && 253 + server->probe.rtt < rtt) { 254 + pref = i; 255 + rtt = server->probe.rtt; 256 + } 257 + 258 + remove_wait_queue(&server->probe_wq, &waits[i]); 259 + } 260 + } 261 + 262 + kfree(waits); 263 + 264 + if (pref == -1 && signal_pending(current)) 265 + return -ERESTARTSYS; 266 + 267 + if (pref >= 0) 268 + slist->preferred = pref; 269 + return 0; 270 + }
+298 -283
fs/afs/fsclient.c
··· 17 17 #include "internal.h" 18 18 #include "afs_fs.h" 19 19 #include "xdr_fs.h" 20 + #include "protocol_yfs.h" 20 21 21 22 static const struct afs_fid afs_zero_fid; 22 - 23 - /* 24 - * We need somewhere to discard into in case the server helpfully returns more 25 - * than we asked for in FS.FetchData{,64}. 26 - */ 27 - static u8 afs_discard_buffer[64]; 28 23 29 24 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi) 30 25 { ··· 70 75 struct timespec64 t; 71 76 umode_t mode; 72 77 73 - t.tv_sec = status->mtime_client; 74 - t.tv_nsec = 0; 78 + t = status->mtime_client; 75 79 vnode->vfs_inode.i_ctime = t; 76 80 vnode->vfs_inode.i_mtime = t; 77 81 vnode->vfs_inode.i_atime = t; ··· 90 96 if (!(flags & AFS_VNODE_NOT_YET_SET)) { 91 97 if (expected_version && 92 98 *expected_version != status->data_version) { 93 - _debug("vnode modified %llx on {%x:%u} [exp %llx]", 99 + _debug("vnode modified %llx on {%llx:%llu} [exp %llx]", 94 100 (unsigned long long) status->data_version, 95 101 vnode->fid.vid, vnode->fid.vnode, 96 102 (unsigned long long) *expected_version); ··· 164 170 if (type != status->type && 165 171 vnode && 166 172 !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 167 - pr_warning("Vnode %x:%x:%x changed type %u to %u\n", 173 + pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n", 168 174 vnode->fid.vid, 169 175 vnode->fid.vnode, 170 176 vnode->fid.unique, ··· 194 200 EXTRACT_M(mode); 195 201 EXTRACT_M(group); 196 202 197 - status->mtime_client = ntohl(xdr->mtime_client); 198 - status->mtime_server = ntohl(xdr->mtime_server); 203 + status->mtime_client.tv_sec = ntohl(xdr->mtime_client); 204 + status->mtime_client.tv_nsec = 0; 205 + status->mtime_server.tv_sec = ntohl(xdr->mtime_server); 206 + status->mtime_server.tv_nsec = 0; 199 207 status->lock_count = ntohl(xdr->lock_count); 200 208 201 209 size = (u64)ntohl(xdr->size_lo); ··· 229 233 230 234 bad: 231 235 xdr_dump_bad(*_bp); 232 - return afs_protocol_error(call, -EBADMSG); 236 + return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); 233 237 } 234 238 235 239 /* ··· 269 273 270 274 write_seqlock(&vnode->cb_lock); 271 275 272 - if (call->cb_break == afs_cb_break_sum(vnode, cbi)) { 276 + if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) { 273 277 vnode->cb_version = ntohl(*bp++); 274 278 cb_expiry = ntohl(*bp++); 275 279 vnode->cb_type = ntohl(*bp++); ··· 289 293 *_bp = bp; 290 294 } 291 295 292 - static void xdr_decode_AFSCallBack_raw(const __be32 **_bp, 296 + static ktime_t xdr_decode_expiry(struct afs_call *call, u32 expiry) 297 + { 298 + return ktime_add_ns(call->reply_time, expiry * NSEC_PER_SEC); 299 + } 300 + 301 + static void xdr_decode_AFSCallBack_raw(struct afs_call *call, 302 + const __be32 **_bp, 293 303 struct afs_callback *cb) 294 304 { 295 305 const __be32 *bp = *_bp; 296 306 297 307 cb->version = ntohl(*bp++); 298 - cb->expiry = ntohl(*bp++); 308 + cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++)); 299 309 cb->type = ntohl(*bp++); 300 310 *_bp = bp; 301 311 } ··· 313 311 struct afs_volsync *volsync) 314 312 { 315 313 const __be32 *bp = *_bp; 314 + u32 creation; 316 315 317 - volsync->creation = ntohl(*bp++); 316 + creation = ntohl(*bp++); 318 317 bp++; /* spare2 */ 319 318 bp++; /* spare3 */ 320 319 bp++; /* spare4 */ 321 320 bp++; /* spare5 */ 322 321 bp++; /* spare6 */ 323 322 *_bp = bp; 323 + 324 + if (volsync) 325 + volsync->creation = creation; 324 326 } 325 327 326 328 /* ··· 385 379 vs->blocks_in_use = ntohl(*bp++); 386 380 vs->part_blocks_avail = ntohl(*bp++); 387 381 vs->part_max_blocks = ntohl(*bp++); 382 + vs->vol_copy_date = 0; 383 + vs->vol_backup_date = 0; 388 384 *_bp = bp; 389 385 } 390 386 ··· 403 395 if (ret < 0) 404 396 return ret; 405 397 406 - _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 398 + _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 407 399 408 400 /* unmarshall the reply once we've received all of it */ 409 401 bp = call->buffer; 410 - if (afs_decode_status(call, &bp, &vnode->status, vnode, 411 - &call->expected_version, NULL) < 0) 412 - return afs_protocol_error(call, -EBADMSG); 402 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 403 + &call->expected_version, NULL); 404 + if (ret < 0) 405 + return ret; 413 406 xdr_decode_AFSCallBack(call, vnode, &bp); 414 - if (call->reply[1]) 415 - xdr_decode_AFSVolSync(&bp, call->reply[1]); 407 + xdr_decode_AFSVolSync(&bp, call->reply[1]); 416 408 417 409 _leave(" = 0 [done]"); 418 410 return 0; ··· 439 431 struct afs_net *net = afs_v2net(vnode); 440 432 __be32 *bp; 441 433 442 - _enter(",%x,{%x:%u},,", 434 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 435 + return yfs_fs_fetch_file_status(fc, volsync, new_inode); 436 + 437 + _enter(",%x,{%llx:%llu},,", 443 438 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 444 439 445 440 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode, ··· 456 445 call->reply[0] = vnode; 457 446 call->reply[1] = volsync; 458 447 call->expected_version = new_inode ? 1 : vnode->status.data_version; 448 + call->want_reply_time = true; 459 449 460 450 /* marshall the parameters */ 461 451 bp = call->request; ··· 480 468 struct afs_read *req = call->reply[2]; 481 469 const __be32 *bp; 482 470 unsigned int size; 483 - void *buffer; 484 471 int ret; 485 472 486 - _enter("{%u,%zu/%u;%llu/%llu}", 487 - call->unmarshall, call->offset, call->count, 488 - req->remain, req->actual_len); 473 + _enter("{%u,%zu/%llu}", 474 + call->unmarshall, iov_iter_count(&call->iter), req->actual_len); 489 475 490 476 switch (call->unmarshall) { 491 477 case 0: 492 478 req->actual_len = 0; 493 - call->offset = 0; 479 + req->index = 0; 480 + req->offset = req->pos & (PAGE_SIZE - 1); 494 481 call->unmarshall++; 495 - if (call->operation_ID != FSFETCHDATA64) { 496 - call->unmarshall++; 497 - goto no_msw; 482 + if (call->operation_ID == FSFETCHDATA64) { 483 + afs_extract_to_tmp64(call); 484 + } else { 485 + call->tmp_u = htonl(0); 486 + afs_extract_to_tmp(call); 498 487 } 499 488 500 - /* extract the upper part of the returned data length of an 501 - * FSFETCHDATA64 op (which should always be 0 using this 502 - * client) */ 503 - case 1: 504 - _debug("extract data length (MSW)"); 505 - ret = afs_extract_data(call, &call->tmp, 4, true); 506 - if (ret < 0) 507 - return ret; 508 - 509 - req->actual_len = ntohl(call->tmp); 510 - req->actual_len <<= 32; 511 - call->offset = 0; 512 - call->unmarshall++; 513 - 514 - no_msw: 515 489 /* extract the returned data length */ 516 - case 2: 490 + case 1: 517 491 _debug("extract data length"); 518 - ret = afs_extract_data(call, &call->tmp, 4, true); 492 + ret = afs_extract_data(call, true); 519 493 if (ret < 0) 520 494 return ret; 521 495 522 - req->actual_len |= ntohl(call->tmp); 496 + req->actual_len = be64_to_cpu(call->tmp64); 523 497 _debug("DATA length: %llu", req->actual_len); 524 - 525 - req->remain = req->actual_len; 526 - call->offset = req->pos & (PAGE_SIZE - 1); 527 - req->index = 0; 528 - if (req->actual_len == 0) 498 + req->remain = min(req->len, req->actual_len); 499 + if (req->remain == 0) 529 500 goto no_more_data; 501 + 530 502 call->unmarshall++; 531 503 532 504 begin_page: 533 505 ASSERTCMP(req->index, <, req->nr_pages); 534 - if (req->remain > PAGE_SIZE - call->offset) 535 - size = PAGE_SIZE - call->offset; 506 + if (req->remain > PAGE_SIZE - req->offset) 507 + size = PAGE_SIZE - req->offset; 536 508 else 537 509 size = req->remain; 538 - call->count = call->offset + size; 539 - ASSERTCMP(call->count, <=, PAGE_SIZE); 540 - req->remain -= size; 510 + call->bvec[0].bv_len = size; 511 + call->bvec[0].bv_offset = req->offset; 512 + call->bvec[0].bv_page = req->pages[req->index]; 513 + iov_iter_bvec(&call->iter, READ, call->bvec, 1, size); 514 + ASSERTCMP(size, <=, PAGE_SIZE); 541 515 542 516 /* extract the returned data */ 543 - case 3: 544 - _debug("extract data %llu/%llu %zu/%u", 545 - req->remain, req->actual_len, call->offset, call->count); 517 + case 2: 518 + _debug("extract data %zu/%llu", 519 + iov_iter_count(&call->iter), req->remain); 546 520 547 - buffer = kmap(req->pages[req->index]); 548 - ret = afs_extract_data(call, buffer, call->count, true); 549 - kunmap(req->pages[req->index]); 521 + ret = afs_extract_data(call, true); 550 522 if (ret < 0) 551 523 return ret; 552 - if (call->offset == PAGE_SIZE) { 524 + req->remain -= call->bvec[0].bv_len; 525 + req->offset += call->bvec[0].bv_len; 526 + ASSERTCMP(req->offset, <=, PAGE_SIZE); 527 + if (req->offset == PAGE_SIZE) { 528 + req->offset = 0; 553 529 if (req->page_done) 554 530 req->page_done(call, req); 555 531 req->index++; 556 - if (req->remain > 0) { 557 - call->offset = 0; 558 - if (req->index >= req->nr_pages) { 559 - call->unmarshall = 4; 560 - goto begin_discard; 561 - } 532 + if (req->remain > 0) 562 533 goto begin_page; 563 - } 564 534 } 565 - goto no_more_data; 535 + 536 + ASSERTCMP(req->remain, ==, 0); 537 + if (req->actual_len <= req->len) 538 + goto no_more_data; 566 539 567 540 /* Discard any excess data the server gave us */ 568 - begin_discard: 569 - case 4: 570 - size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain); 571 - call->count = size; 572 - _debug("extract discard %llu/%llu %zu/%u", 573 - req->remain, req->actual_len, call->offset, call->count); 541 + iov_iter_discard(&call->iter, READ, req->actual_len - req->len); 542 + call->unmarshall = 3; 543 + case 3: 544 + _debug("extract discard %zu/%llu", 545 + iov_iter_count(&call->iter), req->actual_len - req->len); 574 546 575 - call->offset = 0; 576 - ret = afs_extract_data(call, afs_discard_buffer, call->count, true); 577 - req->remain -= call->offset; 547 + ret = afs_extract_data(call, true); 578 548 if (ret < 0) 579 549 return ret; 580 - if (req->remain > 0) 581 - goto begin_discard; 582 550 583 551 no_more_data: 584 - call->offset = 0; 585 - call->unmarshall = 5; 552 + call->unmarshall = 4; 553 + afs_extract_to_buf(call, (21 + 3 + 6) * 4); 586 554 587 555 /* extract the metadata */ 588 - case 5: 589 - ret = afs_extract_data(call, call->buffer, 590 - (21 + 3 + 6) * 4, false); 556 + case 4: 557 + ret = afs_extract_data(call, false); 591 558 if (ret < 0) 592 559 return ret; 593 560 594 561 bp = call->buffer; 595 - if (afs_decode_status(call, &bp, &vnode->status, vnode, 596 - &vnode->status.data_version, req) < 0) 597 - return afs_protocol_error(call, -EBADMSG); 562 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 563 + &vnode->status.data_version, req); 564 + if (ret < 0) 565 + return ret; 598 566 xdr_decode_AFSCallBack(call, vnode, &bp); 599 - if (call->reply[1]) 600 - xdr_decode_AFSVolSync(&bp, call->reply[1]); 567 + xdr_decode_AFSVolSync(&bp, call->reply[1]); 601 568 602 - call->offset = 0; 603 569 call->unmarshall++; 604 570 605 - case 6: 571 + case 5: 606 572 break; 607 573 } 608 574 609 575 for (; req->index < req->nr_pages; req->index++) { 610 - if (call->count < PAGE_SIZE) 576 + if (req->offset < PAGE_SIZE) 611 577 zero_user_segment(req->pages[req->index], 612 - call->count, PAGE_SIZE); 578 + req->offset, PAGE_SIZE); 613 579 if (req->page_done) 614 580 req->page_done(call, req); 615 - call->count = 0; 581 + req->offset = 0; 616 582 } 617 583 618 584 _leave(" = 0 [done]"); ··· 643 653 call->reply[1] = NULL; /* volsync */ 644 654 call->reply[2] = req; 645 655 call->expected_version = vnode->status.data_version; 656 + call->want_reply_time = true; 646 657 647 658 /* marshall the parameters */ 648 659 bp = call->request; ··· 673 682 struct afs_net *net = afs_v2net(vnode); 674 683 __be32 *bp; 675 684 685 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 686 + return yfs_fs_fetch_data(fc, req); 687 + 676 688 if (upper_32_bits(req->pos) || 677 689 upper_32_bits(req->len) || 678 690 upper_32_bits(req->pos + req->len)) ··· 692 698 call->reply[1] = NULL; /* volsync */ 693 699 call->reply[2] = req; 694 700 call->expected_version = vnode->status.data_version; 701 + call->want_reply_time = true; 695 702 696 703 /* marshall the parameters */ 697 704 bp = call->request; ··· 728 733 /* unmarshall the reply once we've received all of it */ 729 734 bp = call->buffer; 730 735 xdr_decode_AFSFid(&bp, call->reply[1]); 731 - if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 || 732 - afs_decode_status(call, &bp, &vnode->status, vnode, 733 - &call->expected_version, NULL) < 0) 734 - return afs_protocol_error(call, -EBADMSG); 735 - xdr_decode_AFSCallBack_raw(&bp, call->reply[3]); 736 + ret = afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL); 737 + if (ret < 0) 738 + return ret; 739 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 740 + &call->expected_version, NULL); 741 + if (ret < 0) 742 + return ret; 743 + xdr_decode_AFSCallBack_raw(call, &bp, call->reply[3]); 736 744 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 737 745 738 746 _leave(" = 0 [done]"); ··· 776 778 size_t namesz, reqsz, padsz; 777 779 __be32 *bp; 778 780 781 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)){ 782 + if (S_ISDIR(mode)) 783 + return yfs_fs_make_dir(fc, name, mode, current_data_version, 784 + newfid, newstatus, newcb); 785 + else 786 + return yfs_fs_create_file(fc, name, mode, current_data_version, 787 + newfid, newstatus, newcb); 788 + } 789 + 779 790 _enter(""); 780 791 781 792 namesz = strlen(name); ··· 803 796 call->reply[2] = newstatus; 804 797 call->reply[3] = newcb; 805 798 call->expected_version = current_data_version + 1; 799 + call->want_reply_time = true; 806 800 807 801 /* marshall the parameters */ 808 802 bp = call->request; ··· 847 839 848 840 /* unmarshall the reply once we've received all of it */ 849 841 bp = call->buffer; 850 - if (afs_decode_status(call, &bp, &vnode->status, vnode, 851 - &call->expected_version, NULL) < 0) 852 - return afs_protocol_error(call, -EBADMSG); 842 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 843 + &call->expected_version, NULL); 844 + if (ret < 0) 845 + return ret; 853 846 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 854 847 855 848 _leave(" = 0 [done]"); ··· 877 868 /* 878 869 * remove a file or directory 879 870 */ 880 - int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir, 881 - u64 current_data_version) 871 + int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 872 + const char *name, bool isdir, u64 current_data_version) 882 873 { 883 - struct afs_vnode *vnode = fc->vnode; 874 + struct afs_vnode *dvnode = fc->vnode; 884 875 struct afs_call *call; 885 - struct afs_net *net = afs_v2net(vnode); 876 + struct afs_net *net = afs_v2net(dvnode); 886 877 size_t namesz, reqsz, padsz; 887 878 __be32 *bp; 879 + 880 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 881 + return yfs_fs_remove(fc, vnode, name, isdir, current_data_version); 888 882 889 883 _enter(""); 890 884 ··· 902 890 return -ENOMEM; 903 891 904 892 call->key = fc->key; 905 - call->reply[0] = vnode; 893 + call->reply[0] = dvnode; 894 + call->reply[1] = vnode; 906 895 call->expected_version = current_data_version + 1; 907 896 908 897 /* marshall the parameters */ 909 898 bp = call->request; 910 899 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE); 911 - *bp++ = htonl(vnode->fid.vid); 912 - *bp++ = htonl(vnode->fid.vnode); 913 - *bp++ = htonl(vnode->fid.unique); 900 + *bp++ = htonl(dvnode->fid.vid); 901 + *bp++ = htonl(dvnode->fid.vnode); 902 + *bp++ = htonl(dvnode->fid.unique); 914 903 *bp++ = htonl(namesz); 915 904 memcpy(bp, name, namesz); 916 905 bp = (void *) bp + namesz; ··· 921 908 } 922 909 923 910 afs_use_fs_server(call, fc->cbi); 924 - trace_afs_make_fs_call(call, &vnode->fid); 911 + trace_afs_make_fs_call(call, &dvnode->fid); 925 912 return afs_make_call(&fc->ac, call, GFP_NOFS, false); 926 913 } 927 914 ··· 942 929 943 930 /* unmarshall the reply once we've received all of it */ 944 931 bp = call->buffer; 945 - if (afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 || 946 - afs_decode_status(call, &bp, &dvnode->status, dvnode, 947 - &call->expected_version, NULL) < 0) 948 - return afs_protocol_error(call, -EBADMSG); 932 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL); 933 + if (ret < 0) 934 + return ret; 935 + ret = afs_decode_status(call, &bp, &dvnode->status, dvnode, 936 + &call->expected_version, NULL); 937 + if (ret < 0) 938 + return ret; 949 939 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 950 940 951 941 _leave(" = 0 [done]"); ··· 976 960 struct afs_net *net = afs_v2net(vnode); 977 961 size_t namesz, reqsz, padsz; 978 962 __be32 *bp; 963 + 964 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 965 + return yfs_fs_link(fc, vnode, name, current_data_version); 979 966 980 967 _enter(""); 981 968 ··· 1035 1016 /* unmarshall the reply once we've received all of it */ 1036 1017 bp = call->buffer; 1037 1018 xdr_decode_AFSFid(&bp, call->reply[1]); 1038 - if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) || 1039 - afs_decode_status(call, &bp, &vnode->status, vnode, 1040 - &call->expected_version, NULL) < 0) 1041 - return afs_protocol_error(call, -EBADMSG); 1019 + ret = afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL); 1020 + if (ret < 0) 1021 + return ret; 1022 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 1023 + &call->expected_version, NULL); 1024 + if (ret < 0) 1025 + return ret; 1042 1026 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1043 1027 1044 1028 _leave(" = 0 [done]"); ··· 1073 1051 struct afs_net *net = afs_v2net(vnode); 1074 1052 size_t namesz, reqsz, padsz, c_namesz, c_padsz; 1075 1053 __be32 *bp; 1054 + 1055 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1056 + return yfs_fs_symlink(fc, name, contents, current_data_version, 1057 + newfid, newstatus); 1076 1058 1077 1059 _enter(""); 1078 1060 ··· 1148 1122 1149 1123 /* unmarshall the reply once we've received all of it */ 1150 1124 bp = call->buffer; 1151 - if (afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode, 1152 - &call->expected_version, NULL) < 0) 1153 - return afs_protocol_error(call, -EBADMSG); 1154 - if (new_dvnode != orig_dvnode && 1155 - afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode, 1156 - &call->expected_version_2, NULL) < 0) 1157 - return afs_protocol_error(call, -EBADMSG); 1125 + ret = afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode, 1126 + &call->expected_version, NULL); 1127 + if (ret < 0) 1128 + return ret; 1129 + if (new_dvnode != orig_dvnode) { 1130 + ret = afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode, 1131 + &call->expected_version_2, NULL); 1132 + if (ret < 0) 1133 + return ret; 1134 + } 1158 1135 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1159 1136 1160 1137 _leave(" = 0 [done]"); ··· 1189 1160 struct afs_net *net = afs_v2net(orig_dvnode); 1190 1161 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz; 1191 1162 __be32 *bp; 1163 + 1164 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1165 + return yfs_fs_rename(fc, orig_name, 1166 + new_dvnode, new_name, 1167 + current_orig_data_version, 1168 + current_new_data_version); 1192 1169 1193 1170 _enter(""); 1194 1171 ··· 1266 1231 1267 1232 /* unmarshall the reply once we've received all of it */ 1268 1233 bp = call->buffer; 1269 - if (afs_decode_status(call, &bp, &vnode->status, vnode, 1270 - &call->expected_version, NULL) < 0) 1271 - return afs_protocol_error(call, -EBADMSG); 1234 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 1235 + &call->expected_version, NULL); 1236 + if (ret < 0) 1237 + return ret; 1272 1238 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1273 1239 1274 1240 afs_pages_written_back(vnode, call); ··· 1309 1273 struct afs_net *net = afs_v2net(vnode); 1310 1274 __be32 *bp; 1311 1275 1312 - _enter(",%x,{%x:%u},,", 1276 + _enter(",%x,{%llx:%llu},,", 1313 1277 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1314 1278 1315 1279 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64, ··· 1366 1330 loff_t size, pos, i_size; 1367 1331 __be32 *bp; 1368 1332 1369 - _enter(",%x,{%x:%u},,", 1333 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1334 + return yfs_fs_store_data(fc, mapping, first, last, offset, to); 1335 + 1336 + _enter(",%x,{%llx:%llu},,", 1370 1337 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1371 1338 1372 1339 size = (loff_t)to - (loff_t)offset; ··· 1446 1407 1447 1408 /* unmarshall the reply once we've received all of it */ 1448 1409 bp = call->buffer; 1449 - if (afs_decode_status(call, &bp, &vnode->status, vnode, 1450 - &call->expected_version, NULL) < 0) 1451 - return afs_protocol_error(call, -EBADMSG); 1410 + ret = afs_decode_status(call, &bp, &vnode->status, vnode, 1411 + &call->expected_version, NULL); 1412 + if (ret < 0) 1413 + return ret; 1452 1414 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1453 1415 1454 1416 _leave(" = 0 [done]"); ··· 1491 1451 struct afs_net *net = afs_v2net(vnode); 1492 1452 __be32 *bp; 1493 1453 1494 - _enter(",%x,{%x:%u},,", 1454 + _enter(",%x,{%llx:%llu},,", 1495 1455 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1496 1456 1497 1457 ASSERT(attr->ia_valid & ATTR_SIZE); ··· 1538 1498 struct afs_net *net = afs_v2net(vnode); 1539 1499 __be32 *bp; 1540 1500 1541 - _enter(",%x,{%x:%u},,", 1501 + _enter(",%x,{%llx:%llu},,", 1542 1502 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1543 1503 1544 1504 ASSERT(attr->ia_valid & ATTR_SIZE); ··· 1584 1544 struct afs_net *net = afs_v2net(vnode); 1585 1545 __be32 *bp; 1586 1546 1547 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1548 + return yfs_fs_setattr(fc, attr); 1549 + 1587 1550 if (attr->ia_valid & ATTR_SIZE) 1588 1551 return afs_fs_setattr_size(fc, attr); 1589 1552 1590 - _enter(",%x,{%x:%u},,", 1553 + _enter(",%x,{%llx:%llu},,", 1591 1554 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1592 1555 1593 1556 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus, ··· 1624 1581 { 1625 1582 const __be32 *bp; 1626 1583 char *p; 1584 + u32 size; 1627 1585 int ret; 1628 1586 1629 1587 _enter("{%u}", call->unmarshall); 1630 1588 1631 1589 switch (call->unmarshall) { 1632 1590 case 0: 1633 - call->offset = 0; 1634 1591 call->unmarshall++; 1592 + afs_extract_to_buf(call, 12 * 4); 1635 1593 1636 1594 /* extract the returned status record */ 1637 1595 case 1: 1638 1596 _debug("extract status"); 1639 - ret = afs_extract_data(call, call->buffer, 1640 - 12 * 4, true); 1597 + ret = afs_extract_data(call, true); 1641 1598 if (ret < 0) 1642 1599 return ret; 1643 1600 1644 1601 bp = call->buffer; 1645 1602 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]); 1646 - call->offset = 0; 1647 1603 call->unmarshall++; 1604 + afs_extract_to_tmp(call); 1648 1605 1649 1606 /* extract the volume name length */ 1650 1607 case 2: 1651 - ret = afs_extract_data(call, &call->tmp, 4, true); 1608 + ret = afs_extract_data(call, true); 1652 1609 if (ret < 0) 1653 1610 return ret; 1654 1611 1655 1612 call->count = ntohl(call->tmp); 1656 1613 _debug("volname length: %u", call->count); 1657 1614 if (call->count >= AFSNAMEMAX) 1658 - return afs_protocol_error(call, -EBADMSG); 1659 - call->offset = 0; 1615 + return afs_protocol_error(call, -EBADMSG, 1616 + afs_eproto_volname_len); 1617 + size = (call->count + 3) & ~3; /* It's padded */ 1618 + afs_extract_begin(call, call->reply[2], size); 1660 1619 call->unmarshall++; 1661 1620 1662 1621 /* extract the volume name */ 1663 1622 case 3: 1664 1623 _debug("extract volname"); 1665 - if (call->count > 0) { 1666 - ret = afs_extract_data(call, call->reply[2], 1667 - call->count, true); 1668 - if (ret < 0) 1669 - return ret; 1670 - } 1624 + ret = afs_extract_data(call, true); 1625 + if (ret < 0) 1626 + return ret; 1671 1627 1672 1628 p = call->reply[2]; 1673 1629 p[call->count] = 0; 1674 1630 _debug("volname '%s'", p); 1675 - 1676 - call->offset = 0; 1631 + afs_extract_to_tmp(call); 1677 1632 call->unmarshall++; 1678 - 1679 - /* extract the volume name padding */ 1680 - if ((call->count & 3) == 0) { 1681 - call->unmarshall++; 1682 - goto no_volname_padding; 1683 - } 1684 - call->count = 4 - (call->count & 3); 1685 - 1686 - case 4: 1687 - ret = afs_extract_data(call, call->buffer, 1688 - call->count, true); 1689 - if (ret < 0) 1690 - return ret; 1691 - 1692 - call->offset = 0; 1693 - call->unmarshall++; 1694 - no_volname_padding: 1695 1633 1696 1634 /* extract the offline message length */ 1697 - case 5: 1698 - ret = afs_extract_data(call, &call->tmp, 4, true); 1635 + case 4: 1636 + ret = afs_extract_data(call, true); 1699 1637 if (ret < 0) 1700 1638 return ret; 1701 1639 1702 1640 call->count = ntohl(call->tmp); 1703 1641 _debug("offline msg length: %u", call->count); 1704 1642 if (call->count >= AFSNAMEMAX) 1705 - return afs_protocol_error(call, -EBADMSG); 1706 - call->offset = 0; 1643 + return afs_protocol_error(call, -EBADMSG, 1644 + afs_eproto_offline_msg_len); 1645 + size = (call->count + 3) & ~3; /* It's padded */ 1646 + afs_extract_begin(call, call->reply[2], size); 1707 1647 call->unmarshall++; 1708 1648 1709 1649 /* extract the offline message */ 1710 - case 6: 1650 + case 5: 1711 1651 _debug("extract offline"); 1712 - if (call->count > 0) { 1713 - ret = afs_extract_data(call, call->reply[2], 1714 - call->count, true); 1715 - if (ret < 0) 1716 - return ret; 1717 - } 1652 + ret = afs_extract_data(call, true); 1653 + if (ret < 0) 1654 + return ret; 1718 1655 1719 1656 p = call->reply[2]; 1720 1657 p[call->count] = 0; 1721 1658 _debug("offline '%s'", p); 1722 1659 1723 - call->offset = 0; 1660 + afs_extract_to_tmp(call); 1724 1661 call->unmarshall++; 1725 - 1726 - /* extract the offline message padding */ 1727 - if ((call->count & 3) == 0) { 1728 - call->unmarshall++; 1729 - goto no_offline_padding; 1730 - } 1731 - call->count = 4 - (call->count & 3); 1732 - 1733 - case 7: 1734 - ret = afs_extract_data(call, call->buffer, 1735 - call->count, true); 1736 - if (ret < 0) 1737 - return ret; 1738 - 1739 - call->offset = 0; 1740 - call->unmarshall++; 1741 - no_offline_padding: 1742 1662 1743 1663 /* extract the message of the day length */ 1744 - case 8: 1745 - ret = afs_extract_data(call, &call->tmp, 4, true); 1664 + case 6: 1665 + ret = afs_extract_data(call, true); 1746 1666 if (ret < 0) 1747 1667 return ret; 1748 1668 1749 1669 call->count = ntohl(call->tmp); 1750 1670 _debug("motd length: %u", call->count); 1751 1671 if (call->count >= AFSNAMEMAX) 1752 - return afs_protocol_error(call, -EBADMSG); 1753 - call->offset = 0; 1672 + return afs_protocol_error(call, -EBADMSG, 1673 + afs_eproto_motd_len); 1674 + size = (call->count + 3) & ~3; /* It's padded */ 1675 + afs_extract_begin(call, call->reply[2], size); 1754 1676 call->unmarshall++; 1755 1677 1756 1678 /* extract the message of the day */ 1757 - case 9: 1679 + case 7: 1758 1680 _debug("extract motd"); 1759 - if (call->count > 0) { 1760 - ret = afs_extract_data(call, call->reply[2], 1761 - call->count, true); 1762 - if (ret < 0) 1763 - return ret; 1764 - } 1681 + ret = afs_extract_data(call, false); 1682 + if (ret < 0) 1683 + return ret; 1765 1684 1766 1685 p = call->reply[2]; 1767 1686 p[call->count] = 0; 1768 1687 _debug("motd '%s'", p); 1769 1688 1770 - call->offset = 0; 1771 1689 call->unmarshall++; 1772 1690 1773 - /* extract the message of the day padding */ 1774 - call->count = (4 - (call->count & 3)) & 3; 1775 - 1776 - case 10: 1777 - ret = afs_extract_data(call, call->buffer, 1778 - call->count, false); 1779 - if (ret < 0) 1780 - return ret; 1781 - 1782 - call->offset = 0; 1783 - call->unmarshall++; 1784 - case 11: 1691 + case 8: 1785 1692 break; 1786 1693 } 1787 1694 ··· 1770 1777 struct afs_net *net = afs_v2net(vnode); 1771 1778 __be32 *bp; 1772 1779 void *tmpbuf; 1780 + 1781 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1782 + return yfs_fs_get_volume_status(fc, vs); 1773 1783 1774 1784 _enter(""); 1775 1785 ··· 1863 1867 struct afs_net *net = afs_v2net(vnode); 1864 1868 __be32 *bp; 1865 1869 1870 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1871 + return yfs_fs_set_lock(fc, type); 1872 + 1866 1873 _enter(""); 1867 1874 1868 1875 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4); ··· 1898 1899 struct afs_net *net = afs_v2net(vnode); 1899 1900 __be32 *bp; 1900 1901 1902 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1903 + return yfs_fs_extend_lock(fc); 1904 + 1901 1905 _enter(""); 1902 1906 1903 1907 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4); ··· 1931 1929 struct afs_call *call; 1932 1930 struct afs_net *net = afs_v2net(vnode); 1933 1931 __be32 *bp; 1932 + 1933 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 1934 + return yfs_fs_release_lock(fc); 1934 1935 1935 1936 _enter(""); 1936 1937 ··· 2009 2004 u32 count; 2010 2005 int ret; 2011 2006 2012 - _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count); 2007 + _enter("{%u,%zu}", call->unmarshall, iov_iter_count(&call->iter)); 2013 2008 2014 - again: 2015 2009 switch (call->unmarshall) { 2016 2010 case 0: 2017 - call->offset = 0; 2011 + afs_extract_to_tmp(call); 2018 2012 call->unmarshall++; 2019 2013 2020 2014 /* Extract the capabilities word count */ 2021 2015 case 1: 2022 - ret = afs_extract_data(call, &call->tmp, 2023 - 1 * sizeof(__be32), 2024 - true); 2016 + ret = afs_extract_data(call, true); 2025 2017 if (ret < 0) 2026 2018 return ret; 2027 2019 ··· 2026 2024 2027 2025 call->count = count; 2028 2026 call->count2 = count; 2029 - call->offset = 0; 2027 + iov_iter_discard(&call->iter, READ, count * sizeof(__be32)); 2030 2028 call->unmarshall++; 2031 2029 2032 2030 /* Extract capabilities words */ 2033 2031 case 2: 2034 - count = min(call->count, 16U); 2035 - ret = afs_extract_data(call, call->buffer, 2036 - count * sizeof(__be32), 2037 - call->count > 16); 2032 + ret = afs_extract_data(call, false); 2038 2033 if (ret < 0) 2039 2034 return ret; 2040 2035 2041 2036 /* TODO: Examine capabilities */ 2042 2037 2043 - call->count -= count; 2044 - if (call->count > 0) 2045 - goto again; 2046 - call->offset = 0; 2047 2038 call->unmarshall++; 2048 2039 break; 2049 2040 } 2050 2041 2051 2042 _leave(" = 0 [done]"); 2052 2043 return 0; 2044 + } 2045 + 2046 + static void afs_destroy_fs_get_capabilities(struct afs_call *call) 2047 + { 2048 + struct afs_server *server = call->reply[0]; 2049 + 2050 + afs_put_server(call->net, server); 2051 + afs_flat_call_destructor(call); 2053 2052 } 2054 2053 2055 2054 /* ··· 2060 2057 .name = "FS.GetCapabilities", 2061 2058 .op = afs_FS_GetCapabilities, 2062 2059 .deliver = afs_deliver_fs_get_capabilities, 2063 - .destructor = afs_flat_call_destructor, 2060 + .done = afs_fileserver_probe_result, 2061 + .destructor = afs_destroy_fs_get_capabilities, 2064 2062 }; 2065 2063 2066 2064 /* ··· 2071 2067 int afs_fs_get_capabilities(struct afs_net *net, 2072 2068 struct afs_server *server, 2073 2069 struct afs_addr_cursor *ac, 2074 - struct key *key) 2070 + struct key *key, 2071 + unsigned int server_index, 2072 + bool async) 2075 2073 { 2076 2074 struct afs_call *call; 2077 2075 __be32 *bp; ··· 2085 2079 return -ENOMEM; 2086 2080 2087 2081 call->key = key; 2082 + call->reply[0] = afs_get_server(server); 2083 + call->reply[1] = (void *)(long)server_index; 2084 + call->upgrade = true; 2085 + call->want_reply_time = true; 2088 2086 2089 2087 /* marshall the parameters */ 2090 2088 bp = call->request; ··· 2096 2086 2097 2087 /* Can't take a ref on server */ 2098 2088 trace_afs_make_fs_call(call, NULL); 2099 - return afs_make_call(ac, call, GFP_NOFS, false); 2089 + return afs_make_call(ac, call, GFP_NOFS, async); 2100 2090 } 2101 2091 2102 2092 /* ··· 2107 2097 struct afs_file_status *status = call->reply[1]; 2108 2098 struct afs_callback *callback = call->reply[2]; 2109 2099 struct afs_volsync *volsync = call->reply[3]; 2110 - struct afs_vnode *vnode = call->reply[0]; 2100 + struct afs_fid *fid = call->reply[0]; 2111 2101 const __be32 *bp; 2112 2102 int ret; 2113 2103 ··· 2115 2105 if (ret < 0) 2116 2106 return ret; 2117 2107 2118 - _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 2108 + _enter("{%llx:%llu}", fid->vid, fid->vnode); 2119 2109 2120 2110 /* unmarshall the reply once we've received all of it */ 2121 2111 bp = call->buffer; 2122 - afs_decode_status(call, &bp, status, vnode, 2123 - &call->expected_version, NULL); 2124 - callback[call->count].version = ntohl(bp[0]); 2125 - callback[call->count].expiry = ntohl(bp[1]); 2126 - callback[call->count].type = ntohl(bp[2]); 2127 - if (vnode) 2128 - xdr_decode_AFSCallBack(call, vnode, &bp); 2129 - else 2130 - bp += 3; 2131 - if (volsync) 2132 - xdr_decode_AFSVolSync(&bp, volsync); 2112 + ret = afs_decode_status(call, &bp, status, NULL, 2113 + &call->expected_version, NULL); 2114 + if (ret < 0) 2115 + return ret; 2116 + xdr_decode_AFSCallBack_raw(call, &bp, callback); 2117 + xdr_decode_AFSVolSync(&bp, volsync); 2133 2118 2134 2119 _leave(" = 0 [done]"); 2135 2120 return 0; ··· 2153 2148 struct afs_call *call; 2154 2149 __be32 *bp; 2155 2150 2156 - _enter(",%x,{%x:%u},,", 2151 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 2152 + return yfs_fs_fetch_status(fc, net, fid, status, callback, volsync); 2153 + 2154 + _enter(",%x,{%llx:%llu},,", 2157 2155 key_serial(fc->key), fid->vid, fid->vnode); 2158 2156 2159 2157 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4); ··· 2166 2158 } 2167 2159 2168 2160 call->key = fc->key; 2169 - call->reply[0] = NULL; /* vnode for fid[0] */ 2161 + call->reply[0] = fid; 2170 2162 call->reply[1] = status; 2171 2163 call->reply[2] = callback; 2172 2164 call->reply[3] = volsync; 2173 2165 call->expected_version = 1; /* vnode->status.data_version */ 2166 + call->want_reply_time = true; 2174 2167 2175 2168 /* marshall the parameters */ 2176 2169 bp = call->request; ··· 2202 2193 2203 2194 switch (call->unmarshall) { 2204 2195 case 0: 2205 - call->offset = 0; 2196 + afs_extract_to_tmp(call); 2206 2197 call->unmarshall++; 2207 2198 2208 2199 /* Extract the file status count and array in two steps */ 2209 2200 case 1: 2210 2201 _debug("extract status count"); 2211 - ret = afs_extract_data(call, &call->tmp, 4, true); 2202 + ret = afs_extract_data(call, true); 2212 2203 if (ret < 0) 2213 2204 return ret; 2214 2205 2215 2206 tmp = ntohl(call->tmp); 2216 2207 _debug("status count: %u/%u", tmp, call->count2); 2217 2208 if (tmp != call->count2) 2218 - return afs_protocol_error(call, -EBADMSG); 2209 + return afs_protocol_error(call, -EBADMSG, 2210 + afs_eproto_ibulkst_count); 2219 2211 2220 2212 call->count = 0; 2221 2213 call->unmarshall++; 2222 2214 more_counts: 2223 - call->offset = 0; 2215 + afs_extract_to_buf(call, 21 * sizeof(__be32)); 2224 2216 2225 2217 case 2: 2226 2218 _debug("extract status array %u", call->count); 2227 - ret = afs_extract_data(call, call->buffer, 21 * 4, true); 2219 + ret = afs_extract_data(call, true); 2228 2220 if (ret < 0) 2229 2221 return ret; 2230 2222 2231 2223 bp = call->buffer; 2232 2224 statuses = call->reply[1]; 2233 - if (afs_decode_status(call, &bp, &statuses[call->count], 2234 - call->count == 0 ? vnode : NULL, 2235 - NULL, NULL) < 0) 2236 - return afs_protocol_error(call, -EBADMSG); 2225 + ret = afs_decode_status(call, &bp, &statuses[call->count], 2226 + call->count == 0 ? vnode : NULL, 2227 + NULL, NULL); 2228 + if (ret < 0) 2229 + return ret; 2237 2230 2238 2231 call->count++; 2239 2232 if (call->count < call->count2) ··· 2243 2232 2244 2233 call->count = 0; 2245 2234 call->unmarshall++; 2246 - call->offset = 0; 2235 + afs_extract_to_tmp(call); 2247 2236 2248 2237 /* Extract the callback count and array in two steps */ 2249 2238 case 3: 2250 2239 _debug("extract CB count"); 2251 - ret = afs_extract_data(call, &call->tmp, 4, true); 2240 + ret = afs_extract_data(call, true); 2252 2241 if (ret < 0) 2253 2242 return ret; 2254 2243 2255 2244 tmp = ntohl(call->tmp); 2256 2245 _debug("CB count: %u", tmp); 2257 2246 if (tmp != call->count2) 2258 - return afs_protocol_error(call, -EBADMSG); 2247 + return afs_protocol_error(call, -EBADMSG, 2248 + afs_eproto_ibulkst_cb_count); 2259 2249 call->count = 0; 2260 2250 call->unmarshall++; 2261 2251 more_cbs: 2262 - call->offset = 0; 2252 + afs_extract_to_buf(call, 3 * sizeof(__be32)); 2263 2253 2264 2254 case 4: 2265 2255 _debug("extract CB array"); 2266 - ret = afs_extract_data(call, call->buffer, 3 * 4, true); 2256 + ret = afs_extract_data(call, true); 2267 2257 if (ret < 0) 2268 2258 return ret; 2269 2259 ··· 2272 2260 bp = call->buffer; 2273 2261 callbacks = call->reply[2]; 2274 2262 callbacks[call->count].version = ntohl(bp[0]); 2275 - callbacks[call->count].expiry = ntohl(bp[1]); 2263 + callbacks[call->count].expires_at = xdr_decode_expiry(call, ntohl(bp[1])); 2276 2264 callbacks[call->count].type = ntohl(bp[2]); 2277 2265 statuses = call->reply[1]; 2278 2266 if (call->count == 0 && vnode && statuses[0].abort_code == 0) ··· 2281 2269 if (call->count < call->count2) 2282 2270 goto more_cbs; 2283 2271 2284 - call->offset = 0; 2272 + afs_extract_to_buf(call, 6 * sizeof(__be32)); 2285 2273 call->unmarshall++; 2286 2274 2287 2275 case 5: 2288 - ret = afs_extract_data(call, call->buffer, 6 * 4, false); 2276 + ret = afs_extract_data(call, false); 2289 2277 if (ret < 0) 2290 2278 return ret; 2291 2279 2292 2280 bp = call->buffer; 2293 - if (call->reply[3]) 2294 - xdr_decode_AFSVolSync(&bp, call->reply[3]); 2281 + xdr_decode_AFSVolSync(&bp, call->reply[3]); 2295 2282 2296 - call->offset = 0; 2297 2283 call->unmarshall++; 2298 2284 2299 2285 case 6: ··· 2327 2317 __be32 *bp; 2328 2318 int i; 2329 2319 2330 - _enter(",%x,{%x:%u},%u", 2320 + if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) 2321 + return yfs_fs_inline_bulk_status(fc, net, fids, statuses, callbacks, 2322 + nr_fids, volsync); 2323 + 2324 + _enter(",%x,{%llx:%llu},%u", 2331 2325 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids); 2332 2326 2333 2327 call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus, ··· 2348 2334 call->reply[2] = callbacks; 2349 2335 call->reply[3] = volsync; 2350 2336 call->count2 = nr_fids; 2337 + call->want_reply_time = true; 2351 2338 2352 2339 /* marshall the parameters */ 2353 2340 bp = call->request;
+20 -17
fs/afs/inode.c
··· 82 82 default: 83 83 printk("kAFS: AFS vnode with undefined type\n"); 84 84 read_sequnlock_excl(&vnode->cb_lock); 85 - return afs_protocol_error(NULL, -EBADMSG); 85 + return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type); 86 86 } 87 87 88 88 inode->i_blocks = 0; ··· 100 100 struct afs_fs_cursor fc; 101 101 int ret; 102 102 103 - _enter("%s,{%x:%u.%u,S=%lx}", 103 + _enter("%s,{%llx:%llu.%u,S=%lx}", 104 104 vnode->volume->name, 105 105 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique, 106 106 vnode->flags); ··· 127 127 int afs_iget5_test(struct inode *inode, void *opaque) 128 128 { 129 129 struct afs_iget_data *data = opaque; 130 + struct afs_vnode *vnode = AFS_FS_I(inode); 130 131 131 - return inode->i_ino == data->fid.vnode && 132 - inode->i_generation == data->fid.unique; 132 + return memcmp(&vnode->fid, &data->fid, sizeof(data->fid)) == 0; 133 133 } 134 134 135 135 /* ··· 150 150 struct afs_iget_data *data = opaque; 151 151 struct afs_vnode *vnode = AFS_FS_I(inode); 152 152 153 - inode->i_ino = data->fid.vnode; 154 - inode->i_generation = data->fid.unique; 155 153 vnode->fid = data->fid; 156 154 vnode->volume = data->volume; 157 155 156 + /* YFS supports 96-bit vnode IDs, but Linux only supports 157 + * 64-bit inode numbers. 158 + */ 159 + inode->i_ino = data->fid.vnode; 160 + inode->i_generation = data->fid.unique; 158 161 return 0; 159 162 } 160 163 ··· 196 193 return ERR_PTR(-ENOMEM); 197 194 } 198 195 199 - _debug("GOT INODE %p { ino=%lu, vl=%x, vn=%x, u=%x }", 196 + _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }", 200 197 inode, inode->i_ino, data.fid.vid, data.fid.vnode, 201 198 data.fid.unique); 202 199 ··· 255 252 256 253 key.vnode_id = vnode->fid.vnode; 257 254 key.unique = vnode->fid.unique; 258 - key.vnode_id_ext[0] = 0; 259 - key.vnode_id_ext[1] = 0; 255 + key.vnode_id_ext[0] = vnode->fid.vnode >> 32; 256 + key.vnode_id_ext[1] = vnode->fid.vnode_hi; 260 257 aux.data_version = vnode->status.data_version; 261 258 262 259 vnode->cache = fscache_acquire_cookie(vnode->volume->cache, ··· 280 277 struct inode *inode; 281 278 int ret; 282 279 283 - _enter(",{%x:%u.%u},,", fid->vid, fid->vnode, fid->unique); 280 + _enter(",{%llx:%llu.%u},,", fid->vid, fid->vnode, fid->unique); 284 281 285 282 as = sb->s_fs_info; 286 283 data.volume = as->volume; ··· 292 289 return ERR_PTR(-ENOMEM); 293 290 } 294 291 295 - _debug("GOT INODE %p { vl=%x vn=%x, u=%x }", 292 + _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }", 296 293 inode, fid->vid, fid->vnode, fid->unique); 297 294 298 295 vnode = AFS_FS_I(inode); ··· 317 314 * didn't give us a callback) */ 318 315 vnode->cb_version = 0; 319 316 vnode->cb_type = 0; 320 - vnode->cb_expires_at = 0; 317 + vnode->cb_expires_at = ktime_get(); 321 318 } else { 322 319 vnode->cb_version = cb->version; 323 320 vnode->cb_type = cb->type; 324 - vnode->cb_expires_at = cb->expiry; 321 + vnode->cb_expires_at = cb->expires_at; 325 322 vnode->cb_interest = afs_get_cb_interest(cbi); 326 323 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 327 324 } ··· 355 352 */ 356 353 void afs_zap_data(struct afs_vnode *vnode) 357 354 { 358 - _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 355 + _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 359 356 360 357 #ifdef CONFIG_AFS_FSCACHE 361 358 fscache_invalidate(vnode->cache); ··· 385 382 bool valid = false; 386 383 int ret; 387 384 388 - _enter("{v={%x:%u} fl=%lx},%x", 385 + _enter("{v={%llx:%llu} fl=%lx},%x", 389 386 vnode->fid.vid, vnode->fid.vnode, vnode->flags, 390 387 key_serial(key)); 391 388 ··· 504 501 505 502 vnode = AFS_FS_I(inode); 506 503 507 - _enter("{%x:%u.%d}", 504 + _enter("{%llx:%llu.%d}", 508 505 vnode->fid.vid, 509 506 vnode->fid.vnode, 510 507 vnode->fid.unique); ··· 553 550 struct key *key; 554 551 int ret; 555 552 556 - _enter("{%x:%u},{n=%pd},%x", 553 + _enter("{%llx:%llu},{n=%pd},%x", 557 554 vnode->fid.vid, vnode->fid.vnode, dentry, 558 555 attr->ia_valid); 559 556
+286 -38
fs/afs/internal.h
··· 22 22 #include <linux/backing-dev.h> 23 23 #include <linux/uuid.h> 24 24 #include <linux/mm_types.h> 25 + #include <linux/dns_resolver.h> 25 26 #include <net/net_namespace.h> 26 27 #include <net/netns/generic.h> 27 28 #include <net/sock.h> ··· 76 75 u32 version; /* Version */ 77 76 unsigned char max_addrs; 78 77 unsigned char nr_addrs; 79 - unsigned char index; /* Address currently in use */ 78 + unsigned char preferred; /* Preferred address */ 80 79 unsigned char nr_ipv4; /* Number of IPv4 addresses */ 80 + enum dns_record_source source:8; 81 + enum dns_lookup_status status:8; 81 82 unsigned long probed; /* Mask of servers that have been probed */ 82 - unsigned long yfs; /* Mask of servers that are YFS */ 83 + unsigned long failed; /* Mask of addrs that failed locally/ICMP */ 84 + unsigned long responded; /* Mask of addrs that responded */ 83 85 struct sockaddr_rxrpc addrs[]; 84 86 #define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8)) 85 87 }; ··· 92 88 */ 93 89 struct afs_call { 94 90 const struct afs_call_type *type; /* type of call */ 91 + struct afs_addr_list *alist; /* Address is alist[addr_ix] */ 95 92 wait_queue_head_t waitq; /* processes awaiting completion */ 96 93 struct work_struct async_work; /* async I/O processor */ 97 94 struct work_struct work; /* actual work processor */ ··· 103 98 struct afs_cb_interest *cbi; /* Callback interest for server used */ 104 99 void *request; /* request data (first part) */ 105 100 struct address_space *mapping; /* Pages being written from */ 101 + struct iov_iter iter; /* Buffer iterator */ 102 + struct iov_iter *_iter; /* Iterator currently in use */ 103 + union { /* Convenience for ->iter */ 104 + struct kvec kvec[1]; 105 + struct bio_vec bvec[1]; 106 + }; 106 107 void *buffer; /* reply receive buffer */ 107 108 void *reply[4]; /* Where to put the reply */ 108 109 pgoff_t first; /* first page in mapping to deal with */ 109 110 pgoff_t last; /* last page in mapping to deal with */ 110 - size_t offset; /* offset into received data store */ 111 111 atomic_t usage; 112 112 enum afs_call_state state; 113 113 spinlock_t state_lock; 114 114 int error; /* error code */ 115 115 u32 abort_code; /* Remote abort ID or 0 */ 116 + u32 epoch; 116 117 unsigned request_size; /* size of request data */ 117 118 unsigned reply_max; /* maximum size of reply */ 118 119 unsigned first_offset; /* offset into mapping[first] */ ··· 128 117 unsigned count2; /* count used in unmarshalling */ 129 118 }; 130 119 unsigned char unmarshall; /* unmarshalling phase */ 120 + unsigned char addr_ix; /* Address in ->alist */ 131 121 bool incoming; /* T if incoming call */ 132 122 bool send_pages; /* T if data from mapping should be sent */ 133 123 bool need_attention; /* T if RxRPC poked us */ 134 124 bool async; /* T if asynchronous */ 135 125 bool ret_reply0; /* T if should return reply[0] on success */ 136 126 bool upgrade; /* T to request service upgrade */ 127 + bool want_reply_time; /* T if want reply_time */ 137 128 u16 service_id; /* Actual service ID (after upgrade) */ 138 129 unsigned int debug_id; /* Trace ID */ 139 130 u32 operation_ID; /* operation ID for an incoming call */ 140 131 u32 count; /* count for use in unmarshalling */ 141 - __be32 tmp; /* place to extract temporary data */ 132 + union { /* place to extract temporary data */ 133 + struct { 134 + __be32 tmp_u; 135 + __be32 tmp; 136 + } __attribute__((packed)); 137 + __be64 tmp64; 138 + }; 142 139 afs_dataversion_t expected_version; /* Updated version expected from store */ 143 140 afs_dataversion_t expected_version_2; /* 2nd updated version expected from store */ 141 + ktime_t reply_time; /* Time of first reply packet */ 144 142 }; 145 143 146 144 struct afs_call_type { ··· 166 146 167 147 /* Work function */ 168 148 void (*work)(struct work_struct *work); 149 + 150 + /* Call done function (gets called immediately on success or failure) */ 151 + void (*done)(struct afs_call *call); 169 152 }; 170 153 171 154 /* ··· 208 185 refcount_t usage; 209 186 unsigned int index; /* Which page we're reading into */ 210 187 unsigned int nr_pages; 188 + unsigned int offset; /* offset into current page */ 211 189 void (*page_done)(struct afs_call *, struct afs_read *); 212 190 struct page **pages; 213 191 struct page *array[]; ··· 367 343 rwlock_t proc_lock; 368 344 369 345 /* VL server list. */ 370 - rwlock_t vl_addrs_lock; /* Lock on vl_addrs */ 371 - struct afs_addr_list __rcu *vl_addrs; /* List of VL servers */ 346 + rwlock_t vl_servers_lock; /* Lock on vl_servers */ 347 + struct afs_vlserver_list __rcu *vl_servers; 348 + 372 349 u8 name_len; /* Length of name */ 373 350 char name[64 + 1]; /* Cell name, case-flattened and NUL-padded */ 351 + }; 352 + 353 + /* 354 + * Volume Location server record. 355 + */ 356 + struct afs_vlserver { 357 + struct rcu_head rcu; 358 + struct afs_addr_list __rcu *addresses; /* List of addresses for this VL server */ 359 + unsigned long flags; 360 + #define AFS_VLSERVER_FL_PROBED 0 /* The VL server has been probed */ 361 + #define AFS_VLSERVER_FL_PROBING 1 /* VL server is being probed */ 362 + #define AFS_VLSERVER_FL_IS_YFS 2 /* Server is YFS not AFS */ 363 + rwlock_t lock; /* Lock on addresses */ 364 + atomic_t usage; 365 + 366 + /* Probe state */ 367 + wait_queue_head_t probe_wq; 368 + atomic_t probe_outstanding; 369 + spinlock_t probe_lock; 370 + struct { 371 + unsigned int rtt; /* RTT as ktime/64 */ 372 + u32 abort_code; 373 + short error; 374 + bool have_result; 375 + bool responded:1; 376 + bool is_yfs:1; 377 + bool not_yfs:1; 378 + bool local_failure:1; 379 + } probe; 380 + 381 + u16 port; 382 + u16 name_len; /* Length of name */ 383 + char name[]; /* Server name, case-flattened */ 384 + }; 385 + 386 + /* 387 + * Weighted list of Volume Location servers. 388 + */ 389 + struct afs_vlserver_entry { 390 + u16 priority; /* Preference (as SRV) */ 391 + u16 weight; /* Weight (as SRV) */ 392 + enum dns_record_source source:8; 393 + enum dns_lookup_status status:8; 394 + struct afs_vlserver *server; 395 + }; 396 + 397 + struct afs_vlserver_list { 398 + struct rcu_head rcu; 399 + atomic_t usage; 400 + u8 nr_servers; 401 + u8 index; /* Server currently in use */ 402 + u8 preferred; /* Preferred server */ 403 + enum dns_record_source source:8; 404 + enum dns_lookup_status status:8; 405 + rwlock_t lock; 406 + struct afs_vlserver_entry servers[]; 374 407 }; 375 408 376 409 /* ··· 484 403 #define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ 485 404 #define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ 486 405 #define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */ 406 + #define AFS_SERVER_FL_IS_YFS 9 /* Server is YFS not AFS */ 407 + #define AFS_SERVER_FL_NO_RM2 10 /* Fileserver doesn't support YFS.RemoveFile2 */ 408 + #define AFS_SERVER_FL_HAVE_EPOCH 11 /* ->epoch is valid */ 487 409 atomic_t usage; 488 410 u32 addr_version; /* Address list version */ 411 + u32 cm_epoch; /* Server RxRPC epoch */ 489 412 490 413 /* file service access */ 491 414 rwlock_t fs_lock; /* access lock */ ··· 498 413 struct hlist_head cb_volumes; /* List of volume interests on this server */ 499 414 unsigned cb_s_break; /* Break-everything counter. */ 500 415 rwlock_t cb_break_lock; /* Volume finding lock */ 416 + 417 + /* Probe state */ 418 + wait_queue_head_t probe_wq; 419 + atomic_t probe_outstanding; 420 + spinlock_t probe_lock; 421 + struct { 422 + unsigned int rtt; /* RTT as ktime/64 */ 423 + u32 abort_code; 424 + u32 cm_epoch; 425 + short error; 426 + bool have_result; 427 + bool responded:1; 428 + bool is_yfs:1; 429 + bool not_yfs:1; 430 + bool local_failure:1; 431 + bool no_epoch:1; 432 + bool cm_probed:1; 433 + bool said_rebooted:1; 434 + bool said_inconsistent:1; 435 + } probe; 501 436 }; 502 437 503 438 /* ··· 552 447 553 448 struct afs_server_list { 554 449 refcount_t usage; 555 - unsigned short nr_servers; 556 - unsigned short index; /* Server currently in use */ 450 + unsigned char nr_servers; 451 + unsigned char preferred; /* Preferred server */ 557 452 unsigned short vnovol_mask; /* Servers to be skipped due to VNOVOL */ 558 453 unsigned int seq; /* Set to ->servers_seq when installed */ 559 454 rwlock_t lock; ··· 655 550 afs_callback_type_t cb_type; /* type of callback */ 656 551 }; 657 552 553 + static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode) 554 + { 555 + #ifdef CONFIG_AFS_FSCACHE 556 + return vnode->cache; 557 + #else 558 + return NULL; 559 + #endif 560 + } 561 + 658 562 /* 659 563 * cached security record for one user's attempt to access a vnode 660 564 */ ··· 700 586 */ 701 587 struct afs_addr_cursor { 702 588 struct afs_addr_list *alist; /* Current address list (pins ref) */ 703 - struct sockaddr_rxrpc *addr; 704 - u32 abort_code; 705 - unsigned short start; /* Starting point in alist->addrs[] */ 706 - unsigned short index; /* Wrapping offset from start to current addr */ 707 - short error; 708 - bool begun; /* T if we've begun iteration */ 589 + unsigned long tried; /* Tried addresses */ 590 + signed char index; /* Current address */ 709 591 bool responded; /* T if the current address responded */ 592 + unsigned short nr_iterations; /* Number of address iterations */ 593 + short error; 594 + u32 abort_code; 595 + }; 596 + 597 + /* 598 + * Cursor for iterating over a set of volume location servers. 599 + */ 600 + struct afs_vl_cursor { 601 + struct afs_addr_cursor ac; 602 + struct afs_cell *cell; /* The cell we're querying */ 603 + struct afs_vlserver_list *server_list; /* Current server list (pins ref) */ 604 + struct afs_vlserver *server; /* Server on which this resides */ 605 + struct key *key; /* Key for the server */ 606 + unsigned long untried; /* Bitmask of untried servers */ 607 + short index; /* Current server */ 608 + short error; 609 + unsigned short flags; 610 + #define AFS_VL_CURSOR_STOP 0x0001 /* Set to cease iteration */ 611 + #define AFS_VL_CURSOR_RETRY 0x0002 /* Set to do a retry */ 612 + #define AFS_VL_CURSOR_RETRIED 0x0004 /* Set if started a retry */ 613 + unsigned short nr_iterations; /* Number of server iterations */ 710 614 }; 711 615 712 616 /* ··· 736 604 struct afs_server_list *server_list; /* Current server list (pins ref) */ 737 605 struct afs_cb_interest *cbi; /* Server on which this resides (pins ref) */ 738 606 struct key *key; /* Key for the server */ 607 + unsigned long untried; /* Bitmask of untried servers */ 739 608 unsigned int cb_break; /* cb_break + cb_s_break before the call */ 740 609 unsigned int cb_break_2; /* cb_break + cb_s_break (2nd vnode) */ 741 - unsigned char start; /* Initial index in server list */ 742 - unsigned char index; /* Number of servers tried beyond start */ 610 + short index; /* Current server */ 611 + short error; 743 612 unsigned short flags; 744 613 #define AFS_FS_CURSOR_STOP 0x0001 /* Set to cease iteration */ 745 614 #define AFS_FS_CURSOR_VBUSY 0x0002 /* Set if seen VBUSY */ ··· 748 615 #define AFS_FS_CURSOR_VNOVOL 0x0008 /* Set if seen VNOVOL */ 749 616 #define AFS_FS_CURSOR_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */ 750 617 #define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */ 618 + unsigned short nr_iterations; /* Number of server iterations */ 751 619 }; 752 620 753 621 /* ··· 774 640 unsigned short, 775 641 unsigned short); 776 642 extern void afs_put_addrlist(struct afs_addr_list *); 777 - extern struct afs_addr_list *afs_parse_text_addrs(const char *, size_t, char, 778 - unsigned short, unsigned short); 779 - extern struct afs_addr_list *afs_dns_query(struct afs_cell *, time64_t *); 643 + extern struct afs_vlserver_list *afs_parse_text_addrs(struct afs_net *, 644 + const char *, size_t, char, 645 + unsigned short, unsigned short); 646 + extern struct afs_vlserver_list *afs_dns_query(struct afs_cell *, time64_t *); 780 647 extern bool afs_iterate_addresses(struct afs_addr_cursor *); 781 648 extern int afs_end_cursor(struct afs_addr_cursor *); 782 - extern int afs_set_vl_cursor(struct afs_addr_cursor *, struct afs_cell *); 783 649 784 650 extern void afs_merge_fs_addr4(struct afs_addr_list *, __be32, u16); 785 651 extern void afs_merge_fs_addr6(struct afs_addr_list *, __be32 *, u16); ··· 802 668 * callback.c 803 669 */ 804 670 extern void afs_init_callback_state(struct afs_server *); 671 + extern void __afs_break_callback(struct afs_vnode *); 805 672 extern void afs_break_callback(struct afs_vnode *); 806 673 extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); 807 674 ··· 823 688 return vnode->cb_break + vnode->cb_s_break + vnode->cb_v_break; 824 689 } 825 690 826 - static inline unsigned int afs_cb_break_sum(struct afs_vnode *vnode, 827 - struct afs_cb_interest *cbi) 691 + static inline bool afs_cb_is_broken(unsigned int cb_break, 692 + const struct afs_vnode *vnode, 693 + const struct afs_cb_interest *cbi) 828 694 { 829 - return vnode->cb_break + cbi->server->cb_s_break + vnode->volume->cb_v_break; 695 + return !cbi || cb_break != (vnode->cb_break + 696 + cbi->server->cb_s_break + 697 + vnode->volume->cb_v_break); 830 698 } 831 699 832 700 /* ··· 919 781 extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *); 920 782 extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, u64, 921 783 struct afs_fid *, struct afs_file_status *, struct afs_callback *); 922 - extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool, u64); 784 + extern int afs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool, u64); 923 785 extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64); 924 786 extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64, 925 787 struct afs_fid *, struct afs_file_status *); ··· 935 797 extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *, 936 798 struct afs_addr_cursor *, struct key *); 937 799 extern int afs_fs_get_capabilities(struct afs_net *, struct afs_server *, 938 - struct afs_addr_cursor *, struct key *); 800 + struct afs_addr_cursor *, struct key *, unsigned int, bool); 939 801 extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, 940 802 struct afs_fid *, struct afs_file_status *, 941 803 struct afs_callback *, unsigned int, ··· 943 805 extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *, 944 806 struct afs_fid *, struct afs_file_status *, 945 807 struct afs_callback *, struct afs_volsync *); 808 + 809 + /* 810 + * fs_probe.c 811 + */ 812 + extern void afs_fileserver_probe_result(struct afs_call *); 813 + extern int afs_probe_fileservers(struct afs_net *, struct key *, struct afs_server_list *); 814 + extern int afs_wait_for_fs_probes(struct afs_server_list *, unsigned long); 946 815 947 816 /* 948 817 * inode.c ··· 1067 922 extern void __net_exit afs_close_socket(struct afs_net *); 1068 923 extern void afs_charge_preallocation(struct work_struct *); 1069 924 extern void afs_put_call(struct afs_call *); 1070 - extern int afs_queue_call_work(struct afs_call *); 1071 925 extern long afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t, bool); 1072 926 extern struct afs_call *afs_alloc_flat_call(struct afs_net *, 1073 927 const struct afs_call_type *, ··· 1074 930 extern void afs_flat_call_destructor(struct afs_call *); 1075 931 extern void afs_send_empty_reply(struct afs_call *); 1076 932 extern void afs_send_simple_reply(struct afs_call *, const void *, size_t); 1077 - extern int afs_extract_data(struct afs_call *, void *, size_t, bool); 1078 - extern int afs_protocol_error(struct afs_call *, int); 933 + extern int afs_extract_data(struct afs_call *, bool); 934 + extern int afs_protocol_error(struct afs_call *, int, enum afs_eproto_cause); 935 + 936 + static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size) 937 + { 938 + call->kvec[0].iov_base = buf; 939 + call->kvec[0].iov_len = size; 940 + iov_iter_kvec(&call->iter, READ, call->kvec, 1, size); 941 + } 942 + 943 + static inline void afs_extract_to_tmp(struct afs_call *call) 944 + { 945 + afs_extract_begin(call, &call->tmp, sizeof(call->tmp)); 946 + } 947 + 948 + static inline void afs_extract_to_tmp64(struct afs_call *call) 949 + { 950 + afs_extract_begin(call, &call->tmp64, sizeof(call->tmp64)); 951 + } 952 + 953 + static inline void afs_extract_discard(struct afs_call *call, size_t size) 954 + { 955 + iov_iter_discard(&call->iter, READ, size); 956 + } 957 + 958 + static inline void afs_extract_to_buf(struct afs_call *call, size_t size) 959 + { 960 + afs_extract_begin(call, call->buffer, size); 961 + } 1079 962 1080 963 static inline int afs_transfer_reply(struct afs_call *call) 1081 964 { 1082 - return afs_extract_data(call, call->buffer, call->reply_max, false); 965 + return afs_extract_data(call, false); 1083 966 } 1084 967 1085 968 static inline bool afs_check_call_state(struct afs_call *call, ··· 1183 1012 extern void afs_manage_servers(struct work_struct *); 1184 1013 extern void afs_servers_timer(struct timer_list *); 1185 1014 extern void __net_exit afs_purge_servers(struct afs_net *); 1186 - extern bool afs_probe_fileserver(struct afs_fs_cursor *); 1187 1015 extern bool afs_check_server_record(struct afs_fs_cursor *, struct afs_server *); 1188 1016 1189 1017 /* ··· 1209 1039 /* 1210 1040 * vlclient.c 1211 1041 */ 1212 - extern struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_net *, 1213 - struct afs_addr_cursor *, 1214 - struct key *, const char *, int); 1215 - extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_net *, struct afs_addr_cursor *, 1216 - struct key *, const uuid_t *); 1217 - extern int afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *, struct key *); 1218 - extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_net *, struct afs_addr_cursor *, 1219 - struct key *, const uuid_t *); 1042 + extern struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *, 1043 + const char *, int); 1044 + extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uuid_t *); 1045 + extern int afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *, struct key *, 1046 + struct afs_vlserver *, unsigned int, bool); 1047 + extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *); 1048 + 1049 + /* 1050 + * vl_probe.c 1051 + */ 1052 + extern void afs_vlserver_probe_result(struct afs_call *); 1053 + extern int afs_send_vl_probes(struct afs_net *, struct key *, struct afs_vlserver_list *); 1054 + extern int afs_wait_for_vl_probes(struct afs_vlserver_list *, unsigned long); 1055 + 1056 + /* 1057 + * vl_rotate.c 1058 + */ 1059 + extern bool afs_begin_vlserver_operation(struct afs_vl_cursor *, 1060 + struct afs_cell *, struct key *); 1061 + extern bool afs_select_vlserver(struct afs_vl_cursor *); 1062 + extern bool afs_select_current_vlserver(struct afs_vl_cursor *); 1063 + extern int afs_end_vlserver_operation(struct afs_vl_cursor *); 1064 + 1065 + /* 1066 + * vlserver_list.c 1067 + */ 1068 + static inline struct afs_vlserver *afs_get_vlserver(struct afs_vlserver *vlserver) 1069 + { 1070 + atomic_inc(&vlserver->usage); 1071 + return vlserver; 1072 + } 1073 + 1074 + static inline struct afs_vlserver_list *afs_get_vlserverlist(struct afs_vlserver_list *vllist) 1075 + { 1076 + if (vllist) 1077 + atomic_inc(&vllist->usage); 1078 + return vllist; 1079 + } 1080 + 1081 + extern struct afs_vlserver *afs_alloc_vlserver(const char *, size_t, unsigned short); 1082 + extern void afs_put_vlserver(struct afs_net *, struct afs_vlserver *); 1083 + extern struct afs_vlserver_list *afs_alloc_vlserver_list(unsigned int); 1084 + extern void afs_put_vlserverlist(struct afs_net *, struct afs_vlserver_list *); 1085 + extern struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *, 1086 + const void *, size_t); 1220 1087 1221 1088 /* 1222 1089 * volume.c ··· 1296 1089 extern const struct xattr_handler *afs_xattr_handlers[]; 1297 1090 extern ssize_t afs_listxattr(struct dentry *, char *, size_t); 1298 1091 1092 + /* 1093 + * yfsclient.c 1094 + */ 1095 + extern int yfs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *, bool); 1096 + extern int yfs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *); 1097 + extern int yfs_fs_create_file(struct afs_fs_cursor *, const char *, umode_t, u64, 1098 + struct afs_fid *, struct afs_file_status *, struct afs_callback *); 1099 + extern int yfs_fs_make_dir(struct afs_fs_cursor *, const char *, umode_t, u64, 1100 + struct afs_fid *, struct afs_file_status *, struct afs_callback *); 1101 + extern int yfs_fs_remove_file2(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64); 1102 + extern int yfs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool, u64); 1103 + extern int yfs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64); 1104 + extern int yfs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64, 1105 + struct afs_fid *, struct afs_file_status *); 1106 + extern int yfs_fs_rename(struct afs_fs_cursor *, const char *, 1107 + struct afs_vnode *, const char *, u64, u64); 1108 + extern int yfs_fs_store_data(struct afs_fs_cursor *, struct address_space *, 1109 + pgoff_t, pgoff_t, unsigned, unsigned); 1110 + extern int yfs_fs_setattr(struct afs_fs_cursor *, struct iattr *); 1111 + extern int yfs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *); 1112 + extern int yfs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t); 1113 + extern int yfs_fs_extend_lock(struct afs_fs_cursor *); 1114 + extern int yfs_fs_release_lock(struct afs_fs_cursor *); 1115 + extern int yfs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *, 1116 + struct afs_fid *, struct afs_file_status *, 1117 + struct afs_callback *, struct afs_volsync *); 1118 + extern int yfs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, 1119 + struct afs_fid *, struct afs_file_status *, 1120 + struct afs_callback *, unsigned int, 1121 + struct afs_volsync *); 1299 1122 1300 1123 /* 1301 1124 * Miscellaneous inline functions. ··· 1357 1120 } 1358 1121 } 1359 1122 1123 + static inline int afs_io_error(struct afs_call *call, enum afs_io_error where) 1124 + { 1125 + trace_afs_io_error(call->debug_id, -EIO, where); 1126 + return -EIO; 1127 + } 1128 + 1129 + static inline int afs_bad(struct afs_vnode *vnode, enum afs_file_error where) 1130 + { 1131 + trace_afs_file_error(vnode, -EIO, where); 1132 + return -EIO; 1133 + } 1360 1134 1361 1135 /*****************************************************************************/ 1362 1136 /*
+3 -2
fs/afs/mntpt.c
··· 130 130 goto error_no_page; 131 131 } 132 132 133 - ret = -EIO; 134 - if (PageError(page)) 133 + if (PageError(page)) { 134 + ret = afs_bad(AFS_FS_I(d_inode(mntpt)), afs_file_error_mntpt); 135 135 goto error; 136 + } 136 137 137 138 buf = kmap_atomic(page); 138 139 memcpy(devname, buf, size);
+82 -28
fs/afs/proc.c
··· 17 17 #include <linux/uaccess.h> 18 18 #include "internal.h" 19 19 20 + struct afs_vl_seq_net_private { 21 + struct seq_net_private seq; /* Must be first */ 22 + struct afs_vlserver_list *vllist; 23 + }; 24 + 20 25 static inline struct afs_net *afs_seq2net(struct seq_file *m) 21 26 { 22 27 return afs_net(seq_file_net(m)); ··· 37 32 */ 38 33 static int afs_proc_cells_show(struct seq_file *m, void *v) 39 34 { 40 - struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link); 35 + struct afs_vlserver_list *vllist; 36 + struct afs_cell *cell; 41 37 42 38 if (v == SEQ_START_TOKEN) { 43 39 /* display header on line 1 */ 44 - seq_puts(m, "USE NAME\n"); 40 + seq_puts(m, "USE TTL SV NAME\n"); 45 41 return 0; 46 42 } 47 43 44 + cell = list_entry(v, struct afs_cell, proc_link); 45 + vllist = rcu_dereference(cell->vl_servers); 46 + 48 47 /* display one cell per line on subsequent lines */ 49 - seq_printf(m, "%3u %s\n", atomic_read(&cell->usage), cell->name); 48 + seq_printf(m, "%3u %6lld %2u %s\n", 49 + atomic_read(&cell->usage), 50 + cell->dns_expiry - ktime_get_real_seconds(), 51 + vllist ? vllist->nr_servers : 0, 52 + cell->name); 50 53 return 0; 51 54 } 52 55 ··· 221 208 return 0; 222 209 } 223 210 224 - seq_printf(m, "%3d %08x %s\n", 211 + seq_printf(m, "%3d %08llx %s\n", 225 212 atomic_read(&vol->usage), vol->vid, 226 213 afs_vol_types[vol->type]); 227 214 ··· 260 247 .show = afs_proc_cell_volumes_show, 261 248 }; 262 249 250 + static const char *const dns_record_sources[NR__dns_record_source + 1] = { 251 + [DNS_RECORD_UNAVAILABLE] = "unav", 252 + [DNS_RECORD_FROM_CONFIG] = "cfg", 253 + [DNS_RECORD_FROM_DNS_A] = "A", 254 + [DNS_RECORD_FROM_DNS_AFSDB] = "AFSDB", 255 + [DNS_RECORD_FROM_DNS_SRV] = "SRV", 256 + [DNS_RECORD_FROM_NSS] = "nss", 257 + [NR__dns_record_source] = "[weird]" 258 + }; 259 + 260 + static const char *const dns_lookup_statuses[NR__dns_lookup_status + 1] = { 261 + [DNS_LOOKUP_NOT_DONE] = "no-lookup", 262 + [DNS_LOOKUP_GOOD] = "good", 263 + [DNS_LOOKUP_GOOD_WITH_BAD] = "good/bad", 264 + [DNS_LOOKUP_BAD] = "bad", 265 + [DNS_LOOKUP_GOT_NOT_FOUND] = "not-found", 266 + [DNS_LOOKUP_GOT_LOCAL_FAILURE] = "local-failure", 267 + [DNS_LOOKUP_GOT_TEMP_FAILURE] = "temp-failure", 268 + [DNS_LOOKUP_GOT_NS_FAILURE] = "ns-failure", 269 + [NR__dns_lookup_status] = "[weird]" 270 + }; 271 + 263 272 /* 264 273 * Display the list of Volume Location servers we're using for a cell. 265 274 */ 266 275 static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) 267 276 { 268 - struct sockaddr_rxrpc *addr = v; 277 + const struct afs_vl_seq_net_private *priv = m->private; 278 + const struct afs_vlserver_list *vllist = priv->vllist; 279 + const struct afs_vlserver_entry *entry; 280 + const struct afs_vlserver *vlserver; 281 + const struct afs_addr_list *alist; 282 + int i; 269 283 270 - /* display header on line 1 */ 271 - if (v == (void *)1) { 272 - seq_puts(m, "ADDRESS\n"); 284 + if (v == SEQ_START_TOKEN) { 285 + seq_printf(m, "# source %s, status %s\n", 286 + dns_record_sources[vllist->source], 287 + dns_lookup_statuses[vllist->status]); 273 288 return 0; 274 289 } 275 290 276 - /* display one cell per line on subsequent lines */ 277 - seq_printf(m, "%pISp\n", &addr->transport); 291 + entry = v; 292 + vlserver = entry->server; 293 + alist = rcu_dereference(vlserver->addresses); 294 + 295 + seq_printf(m, "%s [p=%hu w=%hu s=%s,%s]:\n", 296 + vlserver->name, entry->priority, entry->weight, 297 + dns_record_sources[alist ? alist->source : entry->source], 298 + dns_lookup_statuses[alist ? alist->status : entry->status]); 299 + if (alist) { 300 + for (i = 0; i < alist->nr_addrs; i++) 301 + seq_printf(m, " %c %pISpc\n", 302 + alist->preferred == i ? '>' : '-', 303 + &alist->addrs[i].transport); 304 + } 278 305 return 0; 279 306 } 280 307 281 308 static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) 282 309 __acquires(rcu) 283 310 { 284 - struct afs_addr_list *alist; 311 + struct afs_vl_seq_net_private *priv = m->private; 312 + struct afs_vlserver_list *vllist; 285 313 struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 286 314 loff_t pos = *_pos; 287 315 288 316 rcu_read_lock(); 289 317 290 - alist = rcu_dereference(cell->vl_addrs); 318 + vllist = rcu_dereference(cell->vl_servers); 319 + priv->vllist = vllist; 291 320 292 - /* allow for the header line */ 293 - if (!pos) 294 - return (void *) 1; 295 - pos--; 321 + if (pos < 0) 322 + *_pos = pos = 0; 323 + if (pos == 0) 324 + return SEQ_START_TOKEN; 296 325 297 - if (!alist || pos >= alist->nr_addrs) 326 + if (!vllist || pos - 1 >= vllist->nr_servers) 298 327 return NULL; 299 328 300 - return alist->addrs + pos; 329 + return &vllist->servers[pos - 1]; 301 330 } 302 331 303 332 static void *afs_proc_cell_vlservers_next(struct seq_file *m, void *v, 304 333 loff_t *_pos) 305 334 { 306 - struct afs_addr_list *alist; 307 - struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 335 + struct afs_vl_seq_net_private *priv = m->private; 336 + struct afs_vlserver_list *vllist = priv->vllist; 308 337 loff_t pos; 309 338 310 - alist = rcu_dereference(cell->vl_addrs); 311 - 312 339 pos = *_pos; 313 - (*_pos)++; 314 - if (!alist || pos >= alist->nr_addrs) 340 + pos++; 341 + *_pos = pos; 342 + if (!vllist || pos - 1 >= vllist->nr_servers) 315 343 return NULL; 316 344 317 - return alist->addrs + pos; 345 + return &vllist->servers[pos - 1]; 318 346 } 319 347 320 348 static void afs_proc_cell_vlservers_stop(struct seq_file *m, void *v) ··· 391 337 &server->uuid, 392 338 atomic_read(&server->usage), 393 339 &alist->addrs[0].transport, 394 - alist->index == 0 ? "*" : ""); 340 + alist->preferred == 0 ? "*" : ""); 395 341 for (i = 1; i < alist->nr_addrs; i++) 396 342 seq_printf(m, " %pISpc%s\n", 397 343 &alist->addrs[i].transport, 398 - alist->index == i ? "*" : ""); 344 + alist->preferred == i ? "*" : ""); 399 345 return 0; 400 346 } 401 347 ··· 616 562 617 563 if (!proc_create_net_data("vlservers", 0444, dir, 618 564 &afs_proc_cell_vlservers_ops, 619 - sizeof(struct seq_net_private), 565 + sizeof(struct afs_vl_seq_net_private), 620 566 cell) || 621 567 !proc_create_net_data("volumes", 0444, dir, 622 568 &afs_proc_cell_volumes_ops,
+163
fs/afs/protocol_yfs.h
··· 1 + /* YFS protocol bits 2 + * 3 + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #define YFS_FS_SERVICE 2500 13 + #define YFS_CM_SERVICE 2501 14 + 15 + #define YFSCBMAX 1024 16 + 17 + enum YFS_CM_Operations { 18 + YFSCBProbe = 206, /* probe client */ 19 + YFSCBGetLock = 207, /* get contents of CM lock table */ 20 + YFSCBXStatsVersion = 209, /* get version of extended statistics */ 21 + YFSCBGetXStats = 210, /* get contents of extended statistics data */ 22 + YFSCBInitCallBackState3 = 213, /* initialise callback state, version 3 */ 23 + YFSCBProbeUuid = 214, /* check the client hasn't rebooted */ 24 + YFSCBGetServerPrefs = 215, 25 + YFSCBGetCellServDV = 216, 26 + YFSCBGetLocalCell = 217, 27 + YFSCBGetCacheConfig = 218, 28 + YFSCBGetCellByNum = 65537, 29 + YFSCBTellMeAboutYourself = 65538, /* get client capabilities */ 30 + YFSCBCallBack = 64204, 31 + }; 32 + 33 + enum YFS_FS_Operations { 34 + YFSFETCHACL = 64131, /* YFS Fetch file ACL */ 35 + YFSFETCHSTATUS = 64132, /* YFS Fetch file status */ 36 + YFSSTOREACL = 64134, /* YFS Store file ACL */ 37 + YFSSTORESTATUS = 64135, /* YFS Store file status */ 38 + YFSREMOVEFILE = 64136, /* YFS Remove a file */ 39 + YFSCREATEFILE = 64137, /* YFS Create a file */ 40 + YFSRENAME = 64138, /* YFS Rename or move a file or directory */ 41 + YFSSYMLINK = 64139, /* YFS Create a symbolic link */ 42 + YFSLINK = 64140, /* YFS Create a hard link */ 43 + YFSMAKEDIR = 64141, /* YFS Create a directory */ 44 + YFSREMOVEDIR = 64142, /* YFS Remove a directory */ 45 + YFSGETVOLUMESTATUS = 64149, /* YFS Get volume status information */ 46 + YFSSETVOLUMESTATUS = 64150, /* YFS Set volume status information */ 47 + YFSSETLOCK = 64156, /* YFS Request a file lock */ 48 + YFSEXTENDLOCK = 64157, /* YFS Extend a file lock */ 49 + YFSRELEASELOCK = 64158, /* YFS Release a file lock */ 50 + YFSLOOKUP = 64161, /* YFS lookup file in directory */ 51 + YFSFLUSHCPS = 64165, 52 + YFSFETCHOPAQUEACL = 64168, 53 + YFSWHOAMI = 64170, 54 + YFSREMOVEACL = 64171, 55 + YFSREMOVEFILE2 = 64173, 56 + YFSSTOREOPAQUEACL2 = 64174, 57 + YFSINLINEBULKSTATUS = 64536, /* YFS Fetch multiple file statuses with errors */ 58 + YFSFETCHDATA64 = 64537, /* YFS Fetch file data */ 59 + YFSSTOREDATA64 = 64538, /* YFS Store file data */ 60 + YFSUPDATESYMLINK = 64540, 61 + }; 62 + 63 + struct yfs_xdr_u64 { 64 + __be32 msw; 65 + __be32 lsw; 66 + } __packed; 67 + 68 + static inline u64 xdr_to_u64(const struct yfs_xdr_u64 x) 69 + { 70 + return ((u64)ntohl(x.msw) << 32) | ntohl(x.lsw); 71 + } 72 + 73 + static inline struct yfs_xdr_u64 u64_to_xdr(const u64 x) 74 + { 75 + return (struct yfs_xdr_u64){ .msw = htonl(x >> 32), .lsw = htonl(x) }; 76 + } 77 + 78 + struct yfs_xdr_vnode { 79 + struct yfs_xdr_u64 lo; 80 + __be32 hi; 81 + __be32 unique; 82 + } __packed; 83 + 84 + struct yfs_xdr_YFSFid { 85 + struct yfs_xdr_u64 volume; 86 + struct yfs_xdr_vnode vnode; 87 + } __packed; 88 + 89 + 90 + struct yfs_xdr_YFSFetchStatus { 91 + __be32 type; 92 + __be32 nlink; 93 + struct yfs_xdr_u64 size; 94 + struct yfs_xdr_u64 data_version; 95 + struct yfs_xdr_u64 author; 96 + struct yfs_xdr_u64 owner; 97 + struct yfs_xdr_u64 group; 98 + __be32 mode; 99 + __be32 caller_access; 100 + __be32 anon_access; 101 + struct yfs_xdr_vnode parent; 102 + __be32 data_access_protocol; 103 + struct yfs_xdr_u64 mtime_client; 104 + struct yfs_xdr_u64 mtime_server; 105 + __be32 lock_count; 106 + __be32 abort_code; 107 + } __packed; 108 + 109 + struct yfs_xdr_YFSCallBack { 110 + __be32 version; 111 + struct yfs_xdr_u64 expiration_time; 112 + __be32 type; 113 + } __packed; 114 + 115 + struct yfs_xdr_YFSStoreStatus { 116 + __be32 mask; 117 + __be32 mode; 118 + struct yfs_xdr_u64 mtime_client; 119 + struct yfs_xdr_u64 owner; 120 + struct yfs_xdr_u64 group; 121 + } __packed; 122 + 123 + struct yfs_xdr_RPCFlags { 124 + __be32 rpc_flags; 125 + } __packed; 126 + 127 + struct yfs_xdr_YFSVolSync { 128 + struct yfs_xdr_u64 vol_creation_date; 129 + struct yfs_xdr_u64 vol_update_date; 130 + struct yfs_xdr_u64 max_quota; 131 + struct yfs_xdr_u64 blocks_in_use; 132 + struct yfs_xdr_u64 blocks_avail; 133 + } __packed; 134 + 135 + enum yfs_volume_type { 136 + yfs_volume_type_ro = 0, 137 + yfs_volume_type_rw = 1, 138 + }; 139 + 140 + #define yfs_FVSOnline 0x1 141 + #define yfs_FVSInservice 0x2 142 + #define yfs_FVSBlessed 0x4 143 + #define yfs_FVSNeedsSalvage 0x8 144 + 145 + struct yfs_xdr_YFSFetchVolumeStatus { 146 + struct yfs_xdr_u64 vid; 147 + struct yfs_xdr_u64 parent_id; 148 + __be32 flags; 149 + __be32 type; 150 + struct yfs_xdr_u64 max_quota; 151 + struct yfs_xdr_u64 blocks_in_use; 152 + struct yfs_xdr_u64 part_blocks_avail; 153 + struct yfs_xdr_u64 part_max_blocks; 154 + struct yfs_xdr_u64 vol_copy_date; 155 + struct yfs_xdr_u64 vol_backup_date; 156 + } __packed; 157 + 158 + struct yfs_xdr_YFSStoreVolumeStatus { 159 + __be32 mask; 160 + struct yfs_xdr_u64 min_quota; 161 + struct yfs_xdr_u64 max_quota; 162 + struct yfs_xdr_u64 file_quota; 163 + } __packed;
+212 -90
fs/afs/rotate.c
··· 19 19 #include "afs_fs.h" 20 20 21 21 /* 22 - * Initialise a filesystem server cursor for iterating over FS servers. 23 - */ 24 - static void afs_init_fs_cursor(struct afs_fs_cursor *fc, struct afs_vnode *vnode) 25 - { 26 - memset(fc, 0, sizeof(*fc)); 27 - } 28 - 29 - /* 30 22 * Begin an operation on the fileserver. 31 23 * 32 24 * Fileserver operations are serialised on the server by vnode, so we serialise ··· 27 35 bool afs_begin_vnode_operation(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 28 36 struct key *key) 29 37 { 30 - afs_init_fs_cursor(fc, vnode); 38 + memset(fc, 0, sizeof(*fc)); 31 39 fc->vnode = vnode; 32 40 fc->key = key; 33 41 fc->ac.error = SHRT_MAX; 42 + fc->error = -EDESTADDRREQ; 34 43 35 44 if (mutex_lock_interruptible(&vnode->io_lock) < 0) { 36 - fc->ac.error = -EINTR; 45 + fc->error = -EINTR; 37 46 fc->flags |= AFS_FS_CURSOR_STOP; 38 47 return false; 39 48 } ··· 58 65 fc->server_list = afs_get_serverlist(vnode->volume->servers); 59 66 read_unlock(&vnode->volume->servers_lock); 60 67 68 + fc->untried = (1UL << fc->server_list->nr_servers) - 1; 69 + fc->index = READ_ONCE(fc->server_list->preferred); 70 + 61 71 cbi = vnode->cb_interest; 62 72 if (cbi) { 63 73 /* See if the vnode's preferred record is still available */ 64 74 for (i = 0; i < fc->server_list->nr_servers; i++) { 65 75 if (fc->server_list->servers[i].cb_interest == cbi) { 66 - fc->start = i; 76 + fc->index = i; 67 77 goto found_interest; 68 78 } 69 79 } ··· 76 80 * and have to return an error. 77 81 */ 78 82 if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) { 79 - fc->ac.error = -ESTALE; 83 + fc->error = -ESTALE; 80 84 return false; 81 85 } 82 86 ··· 90 94 91 95 afs_put_cb_interest(afs_v2net(vnode), cbi); 92 96 cbi = NULL; 93 - } else { 94 - fc->start = READ_ONCE(fc->server_list->index); 95 97 } 96 98 97 99 found_interest: 98 - fc->index = fc->start; 99 100 return true; 100 101 } 101 102 ··· 110 117 default: m = "busy"; break; 111 118 } 112 119 113 - pr_notice("kAFS: Volume %u '%s' is %s\n", volume->vid, volume->name, m); 120 + pr_notice("kAFS: Volume %llu '%s' is %s\n", volume->vid, volume->name, m); 114 121 } 115 122 116 123 /* ··· 120 127 { 121 128 msleep_interruptible(1000); 122 129 if (signal_pending(current)) { 123 - fc->ac.error = -ERESTARTSYS; 130 + fc->error = -ERESTARTSYS; 124 131 return false; 125 132 } 126 133 ··· 136 143 struct afs_addr_list *alist; 137 144 struct afs_server *server; 138 145 struct afs_vnode *vnode = fc->vnode; 146 + u32 rtt, abort_code; 147 + int error = fc->ac.error, i; 139 148 140 - _enter("%u/%u,%u/%u,%d,%d", 141 - fc->index, fc->start, 142 - fc->ac.index, fc->ac.start, 143 - fc->ac.error, fc->ac.abort_code); 149 + _enter("%lx[%d],%lx[%d],%d,%d", 150 + fc->untried, fc->index, 151 + fc->ac.tried, fc->ac.index, 152 + error, fc->ac.abort_code); 144 153 145 154 if (fc->flags & AFS_FS_CURSOR_STOP) { 146 155 _leave(" = f [stopped]"); 147 156 return false; 148 157 } 149 158 159 + fc->nr_iterations++; 160 + 150 161 /* Evaluate the result of the previous operation, if there was one. */ 151 - switch (fc->ac.error) { 162 + switch (error) { 152 163 case SHRT_MAX: 153 164 goto start; 154 165 155 166 case 0: 156 167 default: 157 168 /* Success or local failure. Stop. */ 169 + fc->error = error; 158 170 fc->flags |= AFS_FS_CURSOR_STOP; 159 - _leave(" = f [okay/local %d]", fc->ac.error); 171 + _leave(" = f [okay/local %d]", error); 160 172 return false; 161 173 162 174 case -ECONNABORTED: ··· 176 178 * - May indicate that the fileserver couldn't attach to the vol. 177 179 */ 178 180 if (fc->flags & AFS_FS_CURSOR_VNOVOL) { 179 - fc->ac.error = -EREMOTEIO; 181 + fc->error = -EREMOTEIO; 180 182 goto next_server; 181 183 } 182 184 ··· 185 187 write_unlock(&vnode->volume->servers_lock); 186 188 187 189 set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags); 188 - fc->ac.error = afs_check_volume_status(vnode->volume, fc->key); 189 - if (fc->ac.error < 0) 190 - goto failed; 190 + error = afs_check_volume_status(vnode->volume, fc->key); 191 + if (error < 0) 192 + goto failed_set_error; 191 193 192 194 if (test_bit(AFS_VOLUME_DELETED, &vnode->volume->flags)) { 193 - fc->ac.error = -ENOMEDIUM; 195 + fc->error = -ENOMEDIUM; 194 196 goto failed; 195 197 } 196 198 ··· 198 200 * it's the fileserver having trouble. 199 201 */ 200 202 if (vnode->volume->servers == fc->server_list) { 201 - fc->ac.error = -EREMOTEIO; 203 + fc->error = -EREMOTEIO; 202 204 goto next_server; 203 205 } 204 206 ··· 213 215 case VONLINE: 214 216 case VDISKFULL: 215 217 case VOVERQUOTA: 216 - fc->ac.error = afs_abort_to_error(fc->ac.abort_code); 218 + fc->error = afs_abort_to_error(fc->ac.abort_code); 217 219 goto next_server; 218 220 219 221 case VOFFLINE: ··· 222 224 clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags); 223 225 } 224 226 if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) { 225 - fc->ac.error = -EADV; 227 + fc->error = -EADV; 226 228 goto failed; 227 229 } 228 230 if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) { 229 - fc->ac.error = -ESTALE; 231 + fc->error = -ESTALE; 230 232 goto failed; 231 233 } 232 234 goto busy; ··· 238 240 * have a file lock we need to maintain. 239 241 */ 240 242 if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) { 241 - fc->ac.error = -EBUSY; 243 + fc->error = -EBUSY; 242 244 goto failed; 243 245 } 244 246 if (!test_and_set_bit(AFS_VOLUME_BUSY, &vnode->volume->flags)) { ··· 267 269 * honour, just in case someone sets up a loop. 268 270 */ 269 271 if (fc->flags & AFS_FS_CURSOR_VMOVED) { 270 - fc->ac.error = -EREMOTEIO; 272 + fc->error = -EREMOTEIO; 271 273 goto failed; 272 274 } 273 275 fc->flags |= AFS_FS_CURSOR_VMOVED; 274 276 275 277 set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags); 276 278 set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags); 277 - fc->ac.error = afs_check_volume_status(vnode->volume, fc->key); 278 - if (fc->ac.error < 0) 279 - goto failed; 279 + error = afs_check_volume_status(vnode->volume, fc->key); 280 + if (error < 0) 281 + goto failed_set_error; 280 282 281 283 /* If the server list didn't change, then the VLDB is 282 284 * out of sync with the fileservers. This is hopefully ··· 288 290 * TODO: Retry a few times with sleeps. 289 291 */ 290 292 if (vnode->volume->servers == fc->server_list) { 291 - fc->ac.error = -ENOMEDIUM; 293 + fc->error = -ENOMEDIUM; 292 294 goto failed; 293 295 } 294 296 ··· 297 299 default: 298 300 clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags); 299 301 clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags); 300 - fc->ac.error = afs_abort_to_error(fc->ac.abort_code); 302 + fc->error = afs_abort_to_error(fc->ac.abort_code); 301 303 goto failed; 302 304 } 303 305 306 + case -ETIMEDOUT: 307 + case -ETIME: 308 + if (fc->error != -EDESTADDRREQ) 309 + goto iterate_address; 310 + /* Fall through */ 304 311 case -ENETUNREACH: 305 312 case -EHOSTUNREACH: 306 313 case -ECONNREFUSED: 307 - case -ETIMEDOUT: 308 - case -ETIME: 309 314 _debug("no conn"); 315 + fc->error = error; 310 316 goto iterate_address; 311 317 312 318 case -ECONNRESET: 313 319 _debug("call reset"); 320 + fc->error = error; 314 321 goto failed; 315 322 } 316 323 ··· 331 328 /* See if we need to do an update of the volume record. Note that the 332 329 * volume may have moved or even have been deleted. 333 330 */ 334 - fc->ac.error = afs_check_volume_status(vnode->volume, fc->key); 335 - if (fc->ac.error < 0) 336 - goto failed; 331 + error = afs_check_volume_status(vnode->volume, fc->key); 332 + if (error < 0) 333 + goto failed_set_error; 337 334 338 335 if (!afs_start_fs_iteration(fc, vnode)) 339 336 goto failed; 340 337 341 - use_server: 342 - _debug("use"); 338 + _debug("__ VOL %llx __", vnode->volume->vid); 339 + error = afs_probe_fileservers(afs_v2net(vnode), fc->key, fc->server_list); 340 + if (error < 0) 341 + goto failed_set_error; 342 + 343 + pick_server: 344 + _debug("pick [%lx]", fc->untried); 345 + 346 + error = afs_wait_for_fs_probes(fc->server_list, fc->untried); 347 + if (error < 0) 348 + goto failed_set_error; 349 + 350 + /* Pick the untried server with the lowest RTT. If we have outstanding 351 + * callbacks, we stick with the server we're already using if we can. 352 + */ 353 + if (fc->cbi) { 354 + _debug("cbi %u", fc->index); 355 + if (test_bit(fc->index, &fc->untried)) 356 + goto selected_server; 357 + afs_put_cb_interest(afs_v2net(vnode), fc->cbi); 358 + fc->cbi = NULL; 359 + _debug("nocbi"); 360 + } 361 + 362 + fc->index = -1; 363 + rtt = U32_MAX; 364 + for (i = 0; i < fc->server_list->nr_servers; i++) { 365 + struct afs_server *s = fc->server_list->servers[i].server; 366 + 367 + if (!test_bit(i, &fc->untried) || !s->probe.responded) 368 + continue; 369 + if (s->probe.rtt < rtt) { 370 + fc->index = i; 371 + rtt = s->probe.rtt; 372 + } 373 + } 374 + 375 + if (fc->index == -1) 376 + goto no_more_servers; 377 + 378 + selected_server: 379 + _debug("use %d", fc->index); 380 + __clear_bit(fc->index, &fc->untried); 381 + 343 382 /* We're starting on a different fileserver from the list. We need to 344 383 * check it, create a callback intercept, find its address list and 345 384 * probe its capabilities before we use it. ··· 399 354 * break request before we've finished decoding the reply and 400 355 * installing the vnode. 401 356 */ 402 - fc->ac.error = afs_register_server_cb_interest(vnode, fc->server_list, 403 - fc->index); 404 - if (fc->ac.error < 0) 405 - goto failed; 357 + error = afs_register_server_cb_interest(vnode, fc->server_list, 358 + fc->index); 359 + if (error < 0) 360 + goto failed_set_error; 406 361 407 362 fc->cbi = afs_get_cb_interest(vnode->cb_interest); 408 363 ··· 414 369 415 370 memset(&fc->ac, 0, sizeof(fc->ac)); 416 371 417 - /* Probe the current fileserver if we haven't done so yet. */ 418 - if (!test_bit(AFS_SERVER_FL_PROBED, &server->flags)) { 419 - fc->ac.alist = afs_get_addrlist(alist); 420 - 421 - if (!afs_probe_fileserver(fc)) { 422 - switch (fc->ac.error) { 423 - case -ENOMEM: 424 - case -ERESTARTSYS: 425 - case -EINTR: 426 - goto failed; 427 - default: 428 - goto next_server; 429 - } 430 - } 431 - } 432 - 433 372 if (!fc->ac.alist) 434 373 fc->ac.alist = alist; 435 374 else 436 375 afs_put_addrlist(alist); 437 376 438 - fc->ac.start = READ_ONCE(alist->index); 439 - fc->ac.index = fc->ac.start; 377 + fc->ac.index = -1; 440 378 441 379 iterate_address: 442 380 ASSERT(fc->ac.alist); 443 - _debug("iterate %d/%d", fc->ac.index, fc->ac.alist->nr_addrs); 444 381 /* Iterate over the current server's address list to try and find an 445 382 * address on which it will respond to us. 446 383 */ 447 384 if (!afs_iterate_addresses(&fc->ac)) 448 385 goto next_server; 386 + 387 + _debug("address [%u] %u/%u", fc->index, fc->ac.index, fc->ac.alist->nr_addrs); 449 388 450 389 _leave(" = t"); 451 390 return true; ··· 437 408 next_server: 438 409 _debug("next"); 439 410 afs_end_cursor(&fc->ac); 440 - afs_put_cb_interest(afs_v2net(vnode), fc->cbi); 441 - fc->cbi = NULL; 442 - fc->index++; 443 - if (fc->index >= fc->server_list->nr_servers) 444 - fc->index = 0; 445 - if (fc->index != fc->start) 446 - goto use_server; 411 + goto pick_server; 447 412 413 + no_more_servers: 448 414 /* That's all the servers poked to no good effect. Try again if some 449 415 * of them were busy. 450 416 */ 451 417 if (fc->flags & AFS_FS_CURSOR_VBUSY) 452 418 goto restart_from_beginning; 453 419 454 - fc->ac.error = -EDESTADDRREQ; 455 - goto failed; 420 + abort_code = 0; 421 + error = -EDESTADDRREQ; 422 + for (i = 0; i < fc->server_list->nr_servers; i++) { 423 + struct afs_server *s = fc->server_list->servers[i].server; 424 + int probe_error = READ_ONCE(s->probe.error); 456 425 426 + switch (probe_error) { 427 + case 0: 428 + continue; 429 + default: 430 + if (error == -ETIMEDOUT || 431 + error == -ETIME) 432 + continue; 433 + case -ETIMEDOUT: 434 + case -ETIME: 435 + if (error == -ENOMEM || 436 + error == -ENONET) 437 + continue; 438 + case -ENOMEM: 439 + case -ENONET: 440 + if (error == -ENETUNREACH) 441 + continue; 442 + case -ENETUNREACH: 443 + if (error == -EHOSTUNREACH) 444 + continue; 445 + case -EHOSTUNREACH: 446 + if (error == -ECONNREFUSED) 447 + continue; 448 + case -ECONNREFUSED: 449 + if (error == -ECONNRESET) 450 + continue; 451 + case -ECONNRESET: /* Responded, but call expired. */ 452 + if (error == -ECONNABORTED) 453 + continue; 454 + case -ECONNABORTED: 455 + abort_code = s->probe.abort_code; 456 + error = probe_error; 457 + continue; 458 + } 459 + } 460 + 461 + if (error == -ECONNABORTED) 462 + error = afs_abort_to_error(abort_code); 463 + 464 + failed_set_error: 465 + fc->error = error; 457 466 failed: 458 467 fc->flags |= AFS_FS_CURSOR_STOP; 459 468 afs_end_cursor(&fc->ac); 460 - _leave(" = f [failed %d]", fc->ac.error); 469 + _leave(" = f [failed %d]", fc->error); 461 470 return false; 462 471 } 463 472 ··· 509 442 struct afs_vnode *vnode = fc->vnode; 510 443 struct afs_cb_interest *cbi = vnode->cb_interest; 511 444 struct afs_addr_list *alist; 445 + int error = fc->ac.error; 512 446 513 447 _enter(""); 514 448 515 - switch (fc->ac.error) { 449 + switch (error) { 516 450 case SHRT_MAX: 517 451 if (!cbi) { 518 - fc->ac.error = -ESTALE; 452 + fc->error = -ESTALE; 519 453 fc->flags |= AFS_FS_CURSOR_STOP; 520 454 return false; 521 455 } ··· 529 461 afs_get_addrlist(alist); 530 462 read_unlock(&cbi->server->fs_lock); 531 463 if (!alist) { 532 - fc->ac.error = -ESTALE; 464 + fc->error = -ESTALE; 533 465 fc->flags |= AFS_FS_CURSOR_STOP; 534 466 return false; 535 467 } 536 468 537 469 memset(&fc->ac, 0, sizeof(fc->ac)); 538 470 fc->ac.alist = alist; 539 - fc->ac.start = READ_ONCE(alist->index); 540 - fc->ac.index = fc->ac.start; 471 + fc->ac.index = -1; 541 472 goto iterate_address; 542 473 543 474 case 0: 544 475 default: 545 476 /* Success or local failure. Stop. */ 477 + fc->error = error; 546 478 fc->flags |= AFS_FS_CURSOR_STOP; 547 - _leave(" = f [okay/local %d]", fc->ac.error); 479 + _leave(" = f [okay/local %d]", error); 548 480 return false; 549 481 550 482 case -ECONNABORTED: 483 + fc->error = afs_abort_to_error(fc->ac.abort_code); 551 484 fc->flags |= AFS_FS_CURSOR_STOP; 552 485 _leave(" = f [abort]"); 553 486 return false; ··· 559 490 case -ETIMEDOUT: 560 491 case -ETIME: 561 492 _debug("no conn"); 493 + fc->error = error; 562 494 goto iterate_address; 563 495 } 564 496 ··· 577 507 } 578 508 579 509 /* 510 + * Dump cursor state in the case of the error being EDESTADDRREQ. 511 + */ 512 + static void afs_dump_edestaddrreq(const struct afs_fs_cursor *fc) 513 + { 514 + static int count; 515 + int i; 516 + 517 + if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3) 518 + return; 519 + count++; 520 + 521 + rcu_read_lock(); 522 + 523 + pr_notice("EDESTADDR occurred\n"); 524 + pr_notice("FC: cbb=%x cbb2=%x fl=%hx err=%hd\n", 525 + fc->cb_break, fc->cb_break_2, fc->flags, fc->error); 526 + pr_notice("FC: ut=%lx ix=%d ni=%u\n", 527 + fc->untried, fc->index, fc->nr_iterations); 528 + 529 + if (fc->server_list) { 530 + const struct afs_server_list *sl = fc->server_list; 531 + pr_notice("FC: SL nr=%u pr=%u vnov=%hx\n", 532 + sl->nr_servers, sl->preferred, sl->vnovol_mask); 533 + for (i = 0; i < sl->nr_servers; i++) { 534 + const struct afs_server *s = sl->servers[i].server; 535 + pr_notice("FC: server fl=%lx av=%u %pU\n", 536 + s->flags, s->addr_version, &s->uuid); 537 + if (s->addresses) { 538 + const struct afs_addr_list *a = 539 + rcu_dereference(s->addresses); 540 + pr_notice("FC: - av=%u nr=%u/%u/%u pr=%u\n", 541 + a->version, 542 + a->nr_ipv4, a->nr_addrs, a->max_addrs, 543 + a->preferred); 544 + pr_notice("FC: - pr=%lx R=%lx F=%lx\n", 545 + a->probed, a->responded, a->failed); 546 + if (a == fc->ac.alist) 547 + pr_notice("FC: - current\n"); 548 + } 549 + } 550 + } 551 + 552 + pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n", 553 + fc->ac.tried, fc->ac.index, fc->ac.abort_code, fc->ac.error, 554 + fc->ac.responded, fc->ac.nr_iterations); 555 + rcu_read_unlock(); 556 + } 557 + 558 + /* 580 559 * Tidy up a filesystem cursor and unlock the vnode. 581 560 */ 582 561 int afs_end_vnode_operation(struct afs_fs_cursor *fc) 583 562 { 584 563 struct afs_net *net = afs_v2net(fc->vnode); 585 - int ret; 564 + 565 + if (fc->error == -EDESTADDRREQ || 566 + fc->error == -ENETUNREACH || 567 + fc->error == -EHOSTUNREACH) 568 + afs_dump_edestaddrreq(fc); 586 569 587 570 mutex_unlock(&fc->vnode->io_lock); 588 571 ··· 643 520 afs_put_cb_interest(net, fc->cbi); 644 521 afs_put_serverlist(net, fc->server_list); 645 522 646 - ret = fc->ac.error; 647 - if (ret == -ECONNABORTED) 648 - afs_abort_to_error(fc->ac.abort_code); 523 + if (fc->error == -ECONNABORTED) 524 + fc->error = afs_abort_to_error(fc->ac.abort_code); 649 525 650 - return fc->ac.error; 526 + return fc->error; 651 527 }
+67 -48
fs/afs/rxrpc.c
··· 16 16 #include <net/af_rxrpc.h> 17 17 #include "internal.h" 18 18 #include "afs_cm.h" 19 + #include "protocol_yfs.h" 19 20 20 21 struct workqueue_struct *afs_async_calls; 21 22 ··· 75 74 } 76 75 if (ret < 0) 77 76 goto error_2; 77 + 78 + srx.srx_service = YFS_CM_SERVICE; 79 + ret = kernel_bind(socket, (struct sockaddr *) &srx, sizeof(srx)); 80 + if (ret < 0) 81 + goto error_2; 82 + 83 + /* Ideally, we'd turn on service upgrade here, but we can't because 84 + * OpenAFS is buggy and leaks the userStatus field from packet to 85 + * packet and between FS packets and CB packets - so if we try to do an 86 + * upgrade on an FS packet, OpenAFS will leak that into the CB packet 87 + * it sends back to us. 88 + */ 78 89 79 90 rxrpc_kernel_new_call_notification(socket, afs_rx_new_call, 80 91 afs_rx_discard_new_call); ··· 156 143 INIT_WORK(&call->async_work, afs_process_async_call); 157 144 init_waitqueue_head(&call->waitq); 158 145 spin_lock_init(&call->state_lock); 146 + call->_iter = &call->iter; 159 147 160 148 o = atomic_inc_return(&net->nr_outstanding_calls); 161 149 trace_afs_call(call, afs_call_trace_alloc, 1, o, ··· 190 176 191 177 afs_put_server(call->net, call->cm_server); 192 178 afs_put_cb_interest(call->net, call->cbi); 179 + afs_put_addrlist(call->alist); 193 180 kfree(call->request); 194 181 195 182 trace_afs_call(call, afs_call_trace_free, 0, o, ··· 204 189 } 205 190 206 191 /* 207 - * Queue the call for actual work. Returns 0 unconditionally for convenience. 192 + * Queue the call for actual work. 208 193 */ 209 - int afs_queue_call_work(struct afs_call *call) 194 + static void afs_queue_call_work(struct afs_call *call) 210 195 { 211 - int u = atomic_inc_return(&call->usage); 196 + if (call->type->work) { 197 + int u = atomic_inc_return(&call->usage); 212 198 213 - trace_afs_call(call, afs_call_trace_work, u, 214 - atomic_read(&call->net->nr_outstanding_calls), 215 - __builtin_return_address(0)); 199 + trace_afs_call(call, afs_call_trace_work, u, 200 + atomic_read(&call->net->nr_outstanding_calls), 201 + __builtin_return_address(0)); 216 202 217 - INIT_WORK(&call->work, call->type->work); 203 + INIT_WORK(&call->work, call->type->work); 218 204 219 - if (!queue_work(afs_wq, &call->work)) 220 - afs_put_call(call); 221 - return 0; 205 + if (!queue_work(afs_wq, &call->work)) 206 + afs_put_call(call); 207 + } 222 208 } 223 209 224 210 /* ··· 249 233 goto nomem_free; 250 234 } 251 235 236 + afs_extract_to_buf(call, call->reply_max); 252 237 call->operation_ID = type->op; 253 238 init_waitqueue_head(&call->waitq); 254 239 return call; ··· 303 286 offset = 0; 304 287 } 305 288 306 - iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC, bv, nr, bytes); 289 + iov_iter_bvec(&msg->msg_iter, WRITE, bv, nr, bytes); 307 290 } 308 291 309 292 /* ··· 359 342 long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, 360 343 gfp_t gfp, bool async) 361 344 { 362 - struct sockaddr_rxrpc *srx = ac->addr; 345 + struct sockaddr_rxrpc *srx = &ac->alist->addrs[ac->index]; 363 346 struct rxrpc_call *rxcall; 364 347 struct msghdr msg; 365 348 struct kvec iov[1]; ··· 376 359 atomic_read(&call->net->nr_outstanding_calls)); 377 360 378 361 call->async = async; 362 + call->addr_ix = ac->index; 363 + call->alist = afs_get_addrlist(ac->alist); 379 364 380 365 /* Work out the length we're going to transmit. This is awkward for 381 366 * calls such as FS.StoreData where there's an extra injection of data ··· 409 390 call->debug_id); 410 391 if (IS_ERR(rxcall)) { 411 392 ret = PTR_ERR(rxcall); 393 + call->error = ret; 412 394 goto error_kill_call; 413 395 } 414 396 ··· 421 401 422 402 msg.msg_name = NULL; 423 403 msg.msg_namelen = 0; 424 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 1, 425 - call->request_size); 404 + iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, call->request_size); 426 405 msg.msg_control = NULL; 427 406 msg.msg_controllen = 0; 428 407 msg.msg_flags = MSG_WAITALL | (call->send_pages ? MSG_MORE : 0); ··· 451 432 rxrpc_kernel_abort_call(call->net->socket, rxcall, 452 433 RX_USER_ABORT, ret, "KSD"); 453 434 } else { 454 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, NULL, 0, 0); 435 + iov_iter_kvec(&msg.msg_iter, READ, NULL, 0, 0); 455 436 rxrpc_kernel_recv_data(call->net->socket, rxcall, 456 437 &msg.msg_iter, false, 457 438 &call->abort_code, &call->service_id); ··· 461 442 call->error = ret; 462 443 trace_afs_call_done(call); 463 444 error_kill_call: 445 + if (call->type->done) 446 + call->type->done(call); 464 447 afs_put_call(call); 465 448 ac->error = ret; 466 449 _leave(" = %d", ret); ··· 487 466 state == AFS_CALL_SV_AWAIT_ACK 488 467 ) { 489 468 if (state == AFS_CALL_SV_AWAIT_ACK) { 490 - struct iov_iter iter; 491 - 492 - iov_iter_kvec(&iter, READ | ITER_KVEC, NULL, 0, 0); 469 + iov_iter_kvec(&call->iter, READ, NULL, 0, 0); 493 470 ret = rxrpc_kernel_recv_data(call->net->socket, 494 - call->rxcall, &iter, false, 495 - &remote_abort, 471 + call->rxcall, &call->iter, 472 + false, &remote_abort, 496 473 &call->service_id); 497 - trace_afs_recv_data(call, 0, 0, false, ret); 474 + trace_afs_receive_data(call, &call->iter, false, ret); 498 475 499 476 if (ret == -EINPROGRESS || ret == -EAGAIN) 500 477 return; ··· 504 485 return; 505 486 } 506 487 488 + if (call->want_reply_time && 489 + rxrpc_kernel_get_reply_time(call->net->socket, 490 + call->rxcall, 491 + &call->reply_time)) 492 + call->want_reply_time = false; 493 + 507 494 ret = call->type->deliver(call); 508 495 state = READ_ONCE(call->state); 509 496 switch (ret) { 510 497 case 0: 498 + afs_queue_call_work(call); 511 499 if (state == AFS_CALL_CL_PROC_REPLY) { 512 500 if (call->cbi) 513 501 set_bit(AFS_SERVER_FL_MAY_HAVE_CB, ··· 526 500 case -EINPROGRESS: 527 501 case -EAGAIN: 528 502 goto out; 529 - case -EIO: 530 503 case -ECONNABORTED: 531 504 ASSERTCMP(state, ==, AFS_CALL_COMPLETE); 532 505 goto done; ··· 534 509 rxrpc_kernel_abort_call(call->net->socket, call->rxcall, 535 510 abort_code, ret, "KIV"); 536 511 goto local_abort; 512 + case -EIO: 513 + pr_err("kAFS: Call %u in bad state %u\n", 514 + call->debug_id, state); 515 + /* Fall through */ 537 516 case -ENODATA: 538 517 case -EBADMSG: 539 518 case -EMSGSIZE: ··· 546 517 if (state != AFS_CALL_CL_AWAIT_REPLY) 547 518 abort_code = RXGEN_SS_UNMARSHAL; 548 519 rxrpc_kernel_abort_call(call->net->socket, call->rxcall, 549 - abort_code, -EBADMSG, "KUM"); 520 + abort_code, ret, "KUM"); 550 521 goto local_abort; 551 522 } 552 523 } 553 524 554 525 done: 526 + if (call->type->done) 527 + call->type->done(call); 555 528 if (state == AFS_CALL_COMPLETE && call->incoming) 556 529 afs_put_call(call); 557 530 out: ··· 759 728 call->async = true; 760 729 call->state = AFS_CALL_SV_AWAIT_OP_ID; 761 730 init_waitqueue_head(&call->waitq); 731 + afs_extract_to_tmp(call); 762 732 } 763 733 764 734 if (rxrpc_kernel_charge_accept(net->socket, ··· 805 773 { 806 774 int ret; 807 775 808 - _enter("{%zu}", call->offset); 809 - 810 - ASSERTCMP(call->offset, <, 4); 776 + _enter("{%zu}", iov_iter_count(call->_iter)); 811 777 812 778 /* the operation ID forms the first four bytes of the request data */ 813 - ret = afs_extract_data(call, &call->tmp, 4, true); 779 + ret = afs_extract_data(call, true); 814 780 if (ret < 0) 815 781 return ret; 816 782 817 783 call->operation_ID = ntohl(call->tmp); 818 784 afs_set_call_state(call, AFS_CALL_SV_AWAIT_OP_ID, AFS_CALL_SV_AWAIT_REQUEST); 819 - call->offset = 0; 820 785 821 786 /* ask the cache manager to route the call (it'll change the call type 822 787 * if successful) */ ··· 854 825 855 826 msg.msg_name = NULL; 856 827 msg.msg_namelen = 0; 857 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, NULL, 0, 0); 828 + iov_iter_kvec(&msg.msg_iter, WRITE, NULL, 0, 0); 858 829 msg.msg_control = NULL; 859 830 msg.msg_controllen = 0; 860 831 msg.msg_flags = 0; ··· 893 864 iov[0].iov_len = len; 894 865 msg.msg_name = NULL; 895 866 msg.msg_namelen = 0; 896 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iov, 1, len); 867 + iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len); 897 868 msg.msg_control = NULL; 898 869 msg.msg_controllen = 0; 899 870 msg.msg_flags = 0; ··· 917 888 /* 918 889 * Extract a piece of data from the received data socket buffers. 919 890 */ 920 - int afs_extract_data(struct afs_call *call, void *buf, size_t count, 921 - bool want_more) 891 + int afs_extract_data(struct afs_call *call, bool want_more) 922 892 { 923 893 struct afs_net *net = call->net; 924 - struct iov_iter iter; 925 - struct kvec iov; 894 + struct iov_iter *iter = call->_iter; 926 895 enum afs_call_state state; 927 896 u32 remote_abort = 0; 928 897 int ret; 929 898 930 - _enter("{%s,%zu},,%zu,%d", 931 - call->type->name, call->offset, count, want_more); 899 + _enter("{%s,%zu},%d", call->type->name, iov_iter_count(iter), want_more); 932 900 933 - ASSERTCMP(call->offset, <=, count); 934 - 935 - iov.iov_base = buf + call->offset; 936 - iov.iov_len = count - call->offset; 937 - iov_iter_kvec(&iter, ITER_KVEC | READ, &iov, 1, count - call->offset); 938 - 939 - ret = rxrpc_kernel_recv_data(net->socket, call->rxcall, &iter, 901 + ret = rxrpc_kernel_recv_data(net->socket, call->rxcall, iter, 940 902 want_more, &remote_abort, 941 903 &call->service_id); 942 - call->offset += (count - call->offset) - iov_iter_count(&iter); 943 - trace_afs_recv_data(call, count, call->offset, want_more, ret); 944 904 if (ret == 0 || ret == -EAGAIN) 945 905 return ret; 946 906 ··· 944 926 break; 945 927 case AFS_CALL_COMPLETE: 946 928 kdebug("prem complete %d", call->error); 947 - return -EIO; 929 + return afs_io_error(call, afs_io_error_extract); 948 930 default: 949 931 break; 950 932 } ··· 958 940 /* 959 941 * Log protocol error production. 960 942 */ 961 - noinline int afs_protocol_error(struct afs_call *call, int error) 943 + noinline int afs_protocol_error(struct afs_call *call, int error, 944 + enum afs_eproto_cause cause) 962 945 { 963 - trace_afs_protocol_error(call, error, __builtin_return_address(0)); 946 + trace_afs_protocol_error(call, error, cause); 964 947 return error; 965 948 }
+7 -6
fs/afs/security.c
··· 126 126 bool changed = false; 127 127 int i, j; 128 128 129 - _enter("{%x:%u},%x,%x", 129 + _enter("{%llx:%llu},%x,%x", 130 130 vnode->fid.vid, vnode->fid.vnode, key_serial(key), caller_access); 131 131 132 132 rcu_read_lock(); ··· 147 147 break; 148 148 } 149 149 150 - if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) { 150 + if (afs_cb_is_broken(cb_break, vnode, 151 + vnode->cb_interest)) { 151 152 changed = true; 152 153 break; 153 154 } ··· 178 177 } 179 178 } 180 179 181 - if (cb_break != afs_cb_break_sum(vnode, vnode->cb_interest)) 180 + if (afs_cb_is_broken(cb_break, vnode, vnode->cb_interest)) 182 181 goto someone_else_changed_it; 183 182 184 183 /* We need a ref on any permits list we want to copy as we'll have to ··· 257 256 258 257 spin_lock(&vnode->lock); 259 258 zap = rcu_access_pointer(vnode->permit_cache); 260 - if (cb_break == afs_cb_break_sum(vnode, vnode->cb_interest) && 259 + if (!afs_cb_is_broken(cb_break, vnode, vnode->cb_interest) && 261 260 zap == permits) 262 261 rcu_assign_pointer(vnode->permit_cache, replacement); 263 262 else ··· 290 289 bool valid = false; 291 290 int i, ret; 292 291 293 - _enter("{%x:%u},%x", 292 + _enter("{%llx:%llu},%x", 294 293 vnode->fid.vid, vnode->fid.vnode, key_serial(key)); 295 294 296 295 /* check the permits to see if we've got one yet */ ··· 350 349 if (mask & MAY_NOT_BLOCK) 351 350 return -ECHILD; 352 351 353 - _enter("{{%x:%u},%lx},%x,", 352 + _enter("{{%llx:%llu},%lx},%x,", 354 353 vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask); 355 354 356 355 key = afs_request_key(vnode->volume->cell);
+19 -126
fs/afs/server.c
··· 13 13 #include <linux/slab.h> 14 14 #include "afs_fs.h" 15 15 #include "internal.h" 16 + #include "protocol_yfs.h" 16 17 17 18 static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */ 18 19 static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */ ··· 231 230 rwlock_init(&server->fs_lock); 232 231 INIT_HLIST_HEAD(&server->cb_volumes); 233 232 rwlock_init(&server->cb_break_lock); 233 + init_waitqueue_head(&server->probe_wq); 234 + spin_lock_init(&server->probe_lock); 234 235 235 236 afs_inc_servers_outstanding(net); 236 237 _leave(" = %p", server); ··· 249 246 static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell, 250 247 struct key *key, const uuid_t *uuid) 251 248 { 252 - struct afs_addr_cursor ac; 253 - struct afs_addr_list *alist; 249 + struct afs_vl_cursor vc; 250 + struct afs_addr_list *alist = NULL; 254 251 int ret; 255 252 256 - ret = afs_set_vl_cursor(&ac, cell); 257 - if (ret < 0) 258 - return ERR_PTR(ret); 259 - 260 - while (afs_iterate_addresses(&ac)) { 261 - if (test_bit(ac.index, &ac.alist->yfs)) 262 - alist = afs_yfsvl_get_endpoints(cell->net, &ac, key, uuid); 263 - else 264 - alist = afs_vl_get_addrs_u(cell->net, &ac, key, uuid); 265 - switch (ac.error) { 266 - case 0: 267 - afs_end_cursor(&ac); 268 - return alist; 269 - case -ECONNABORTED: 270 - ac.error = afs_abort_to_error(ac.abort_code); 271 - goto error; 272 - case -ENOMEM: 273 - case -ENONET: 274 - goto error; 275 - case -ENETUNREACH: 276 - case -EHOSTUNREACH: 277 - case -ECONNREFUSED: 278 - break; 279 - default: 280 - ac.error = -EIO; 281 - goto error; 253 + ret = -ERESTARTSYS; 254 + if (afs_begin_vlserver_operation(&vc, cell, key)) { 255 + while (afs_select_vlserver(&vc)) { 256 + if (test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags)) 257 + alist = afs_yfsvl_get_endpoints(&vc, uuid); 258 + else 259 + alist = afs_vl_get_addrs_u(&vc, uuid); 282 260 } 261 + 262 + ret = afs_end_vlserver_operation(&vc); 283 263 } 284 264 285 - error: 286 - return ERR_PTR(afs_end_cursor(&ac)); 265 + return ret < 0 ? ERR_PTR(ret) : alist; 287 266 } 288 267 289 268 /* ··· 367 382 struct afs_addr_list *alist = rcu_access_pointer(server->addresses); 368 383 struct afs_addr_cursor ac = { 369 384 .alist = alist, 370 - .start = alist->index, 371 - .index = 0, 372 - .addr = &alist->addrs[alist->index], 385 + .index = alist->preferred, 373 386 .error = 0, 374 387 }; 375 388 _enter("%p", server); 376 389 377 390 if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags)) 378 391 afs_fs_give_up_all_callbacks(net, server, &ac, NULL); 392 + 393 + wait_var_event(&server->probe_outstanding, 394 + atomic_read(&server->probe_outstanding) == 0); 379 395 380 396 call_rcu(&server->rcu, afs_server_rcu); 381 397 afs_dec_servers_outstanding(net); ··· 508 522 wait_var_event(&net->servers_outstanding, 509 523 !atomic_read(&net->servers_outstanding)); 510 524 _leave(""); 511 - } 512 - 513 - /* 514 - * Probe a fileserver to find its capabilities. 515 - * 516 - * TODO: Try service upgrade. 517 - */ 518 - static bool afs_do_probe_fileserver(struct afs_fs_cursor *fc) 519 - { 520 - _enter(""); 521 - 522 - fc->ac.addr = NULL; 523 - fc->ac.start = READ_ONCE(fc->ac.alist->index); 524 - fc->ac.index = fc->ac.start; 525 - fc->ac.error = 0; 526 - fc->ac.begun = false; 527 - 528 - while (afs_iterate_addresses(&fc->ac)) { 529 - afs_fs_get_capabilities(afs_v2net(fc->vnode), fc->cbi->server, 530 - &fc->ac, fc->key); 531 - switch (fc->ac.error) { 532 - case 0: 533 - afs_end_cursor(&fc->ac); 534 - set_bit(AFS_SERVER_FL_PROBED, &fc->cbi->server->flags); 535 - return true; 536 - case -ECONNABORTED: 537 - fc->ac.error = afs_abort_to_error(fc->ac.abort_code); 538 - goto error; 539 - case -ENOMEM: 540 - case -ENONET: 541 - goto error; 542 - case -ENETUNREACH: 543 - case -EHOSTUNREACH: 544 - case -ECONNREFUSED: 545 - case -ETIMEDOUT: 546 - case -ETIME: 547 - break; 548 - default: 549 - fc->ac.error = -EIO; 550 - goto error; 551 - } 552 - } 553 - 554 - error: 555 - afs_end_cursor(&fc->ac); 556 - return false; 557 - } 558 - 559 - /* 560 - * If we haven't already, try probing the fileserver to get its capabilities. 561 - * We try not to instigate parallel probes, but it's possible that the parallel 562 - * probes will fail due to authentication failure when ours would succeed. 563 - * 564 - * TODO: Try sending an anonymous probe if an authenticated probe fails. 565 - */ 566 - bool afs_probe_fileserver(struct afs_fs_cursor *fc) 567 - { 568 - bool success; 569 - int ret, retries = 0; 570 - 571 - _enter(""); 572 - 573 - retry: 574 - if (test_bit(AFS_SERVER_FL_PROBED, &fc->cbi->server->flags)) { 575 - _leave(" = t"); 576 - return true; 577 - } 578 - 579 - if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &fc->cbi->server->flags)) { 580 - success = afs_do_probe_fileserver(fc); 581 - clear_bit_unlock(AFS_SERVER_FL_PROBING, &fc->cbi->server->flags); 582 - wake_up_bit(&fc->cbi->server->flags, AFS_SERVER_FL_PROBING); 583 - _leave(" = t"); 584 - return success; 585 - } 586 - 587 - _debug("wait"); 588 - ret = wait_on_bit(&fc->cbi->server->flags, AFS_SERVER_FL_PROBING, 589 - TASK_INTERRUPTIBLE); 590 - if (ret == -ERESTARTSYS) { 591 - fc->ac.error = ret; 592 - _leave(" = f [%d]", ret); 593 - return false; 594 - } 595 - 596 - retries++; 597 - if (retries == 4) { 598 - fc->ac.error = -ESTALE; 599 - _leave(" = f [stale]"); 600 - return false; 601 - } 602 - _debug("retry"); 603 - goto retry; 604 525 } 605 526 606 527 /*
+3 -3
fs/afs/server_list.c
··· 118 118 return false; 119 119 120 120 changed: 121 - /* Maintain the same current server as before if possible. */ 122 - cur = old->servers[old->index].server; 121 + /* Maintain the same preferred server as before if possible. */ 122 + cur = old->servers[old->preferred].server; 123 123 for (j = 0; j < new->nr_servers; j++) { 124 124 if (new->servers[j].server == cur) { 125 - new->index = j; 125 + new->preferred = j; 126 126 break; 127 127 } 128 128 }
+3 -2
fs/afs/super.c
··· 406 406 inode = afs_iget_pseudo_dir(sb, true); 407 407 sb->s_flags |= SB_RDONLY; 408 408 } else { 409 - sprintf(sb->s_id, "%u", as->volume->vid); 409 + sprintf(sb->s_id, "%llu", as->volume->vid); 410 410 afs_activate_volume(as->volume); 411 411 fid.vid = as->volume->vid; 412 412 fid.vnode = 1; 413 + fid.vnode_hi = 0; 413 414 fid.unique = 1; 414 415 inode = afs_iget(sb, params->key, &fid, NULL, NULL, NULL); 415 416 } ··· 664 663 { 665 664 struct afs_vnode *vnode = AFS_FS_I(inode); 666 665 667 - _enter("%p{%x:%u}", inode, vnode->fid.vid, vnode->fid.vnode); 666 + _enter("%p{%llx:%llu}", inode, vnode->fid.vid, vnode->fid.vnode); 668 667 669 668 _debug("DESTROY INODE %p", inode); 670 669
+340
fs/afs/vl_list.c
··· 1 + /* AFS vlserver list management. 2 + * 3 + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the License, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/kernel.h> 13 + #include <linux/slab.h> 14 + #include "internal.h" 15 + 16 + struct afs_vlserver *afs_alloc_vlserver(const char *name, size_t name_len, 17 + unsigned short port) 18 + { 19 + struct afs_vlserver *vlserver; 20 + 21 + vlserver = kzalloc(struct_size(vlserver, name, name_len + 1), 22 + GFP_KERNEL); 23 + if (vlserver) { 24 + atomic_set(&vlserver->usage, 1); 25 + rwlock_init(&vlserver->lock); 26 + init_waitqueue_head(&vlserver->probe_wq); 27 + spin_lock_init(&vlserver->probe_lock); 28 + vlserver->name_len = name_len; 29 + vlserver->port = port; 30 + memcpy(vlserver->name, name, name_len); 31 + } 32 + return vlserver; 33 + } 34 + 35 + static void afs_vlserver_rcu(struct rcu_head *rcu) 36 + { 37 + struct afs_vlserver *vlserver = container_of(rcu, struct afs_vlserver, rcu); 38 + 39 + afs_put_addrlist(rcu_access_pointer(vlserver->addresses)); 40 + kfree_rcu(vlserver, rcu); 41 + } 42 + 43 + void afs_put_vlserver(struct afs_net *net, struct afs_vlserver *vlserver) 44 + { 45 + if (vlserver) { 46 + unsigned int u = atomic_dec_return(&vlserver->usage); 47 + //_debug("VL PUT %p{%u}", vlserver, u); 48 + 49 + if (u == 0) 50 + call_rcu(&vlserver->rcu, afs_vlserver_rcu); 51 + } 52 + } 53 + 54 + struct afs_vlserver_list *afs_alloc_vlserver_list(unsigned int nr_servers) 55 + { 56 + struct afs_vlserver_list *vllist; 57 + 58 + vllist = kzalloc(struct_size(vllist, servers, nr_servers), GFP_KERNEL); 59 + if (vllist) { 60 + atomic_set(&vllist->usage, 1); 61 + rwlock_init(&vllist->lock); 62 + } 63 + 64 + return vllist; 65 + } 66 + 67 + void afs_put_vlserverlist(struct afs_net *net, struct afs_vlserver_list *vllist) 68 + { 69 + if (vllist) { 70 + unsigned int u = atomic_dec_return(&vllist->usage); 71 + 72 + //_debug("VLLS PUT %p{%u}", vllist, u); 73 + if (u == 0) { 74 + int i; 75 + 76 + for (i = 0; i < vllist->nr_servers; i++) { 77 + afs_put_vlserver(net, vllist->servers[i].server); 78 + } 79 + kfree_rcu(vllist, rcu); 80 + } 81 + } 82 + } 83 + 84 + static u16 afs_extract_le16(const u8 **_b) 85 + { 86 + u16 val; 87 + 88 + val = (u16)*(*_b)++ << 0; 89 + val |= (u16)*(*_b)++ << 8; 90 + return val; 91 + } 92 + 93 + /* 94 + * Build a VL server address list from a DNS queried server list. 95 + */ 96 + static struct afs_addr_list *afs_extract_vl_addrs(const u8 **_b, const u8 *end, 97 + u8 nr_addrs, u16 port) 98 + { 99 + struct afs_addr_list *alist; 100 + const u8 *b = *_b; 101 + int ret = -EINVAL; 102 + 103 + alist = afs_alloc_addrlist(nr_addrs, VL_SERVICE, port); 104 + if (!alist) 105 + return ERR_PTR(-ENOMEM); 106 + if (nr_addrs == 0) 107 + return alist; 108 + 109 + for (; nr_addrs > 0 && end - b >= nr_addrs; nr_addrs--) { 110 + struct dns_server_list_v1_address hdr; 111 + __be32 x[4]; 112 + 113 + hdr.address_type = *b++; 114 + 115 + switch (hdr.address_type) { 116 + case DNS_ADDRESS_IS_IPV4: 117 + if (end - b < 4) { 118 + _leave(" = -EINVAL [short inet]"); 119 + goto error; 120 + } 121 + memcpy(x, b, 4); 122 + afs_merge_fs_addr4(alist, x[0], port); 123 + b += 4; 124 + break; 125 + 126 + case DNS_ADDRESS_IS_IPV6: 127 + if (end - b < 16) { 128 + _leave(" = -EINVAL [short inet6]"); 129 + goto error; 130 + } 131 + memcpy(x, b, 16); 132 + afs_merge_fs_addr6(alist, x, port); 133 + b += 16; 134 + break; 135 + 136 + default: 137 + _leave(" = -EADDRNOTAVAIL [unknown af %u]", 138 + hdr.address_type); 139 + ret = -EADDRNOTAVAIL; 140 + goto error; 141 + } 142 + } 143 + 144 + /* Start with IPv6 if available. */ 145 + if (alist->nr_ipv4 < alist->nr_addrs) 146 + alist->preferred = alist->nr_ipv4; 147 + 148 + *_b = b; 149 + return alist; 150 + 151 + error: 152 + *_b = b; 153 + afs_put_addrlist(alist); 154 + return ERR_PTR(ret); 155 + } 156 + 157 + /* 158 + * Build a VL server list from a DNS queried server list. 159 + */ 160 + struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell, 161 + const void *buffer, 162 + size_t buffer_size) 163 + { 164 + const struct dns_server_list_v1_header *hdr = buffer; 165 + struct dns_server_list_v1_server bs; 166 + struct afs_vlserver_list *vllist, *previous; 167 + struct afs_addr_list *addrs; 168 + struct afs_vlserver *server; 169 + const u8 *b = buffer, *end = buffer + buffer_size; 170 + int ret = -ENOMEM, nr_servers, i, j; 171 + 172 + _enter(""); 173 + 174 + /* Check that it's a server list, v1 */ 175 + if (end - b < sizeof(*hdr) || 176 + hdr->hdr.content != DNS_PAYLOAD_IS_SERVER_LIST || 177 + hdr->hdr.version != 1) { 178 + pr_notice("kAFS: Got DNS record [%u,%u] len %zu\n", 179 + hdr->hdr.content, hdr->hdr.version, end - b); 180 + ret = -EDESTADDRREQ; 181 + goto dump; 182 + } 183 + 184 + nr_servers = hdr->nr_servers; 185 + 186 + vllist = afs_alloc_vlserver_list(nr_servers); 187 + if (!vllist) 188 + return ERR_PTR(-ENOMEM); 189 + 190 + vllist->source = (hdr->source < NR__dns_record_source) ? 191 + hdr->source : NR__dns_record_source; 192 + vllist->status = (hdr->status < NR__dns_lookup_status) ? 193 + hdr->status : NR__dns_lookup_status; 194 + 195 + read_lock(&cell->vl_servers_lock); 196 + previous = afs_get_vlserverlist( 197 + rcu_dereference_protected(cell->vl_servers, 198 + lockdep_is_held(&cell->vl_servers_lock))); 199 + read_unlock(&cell->vl_servers_lock); 200 + 201 + b += sizeof(*hdr); 202 + while (end - b >= sizeof(bs)) { 203 + bs.name_len = afs_extract_le16(&b); 204 + bs.priority = afs_extract_le16(&b); 205 + bs.weight = afs_extract_le16(&b); 206 + bs.port = afs_extract_le16(&b); 207 + bs.source = *b++; 208 + bs.status = *b++; 209 + bs.protocol = *b++; 210 + bs.nr_addrs = *b++; 211 + 212 + _debug("extract %u %u %u %u %u %u %*.*s", 213 + bs.name_len, bs.priority, bs.weight, 214 + bs.port, bs.protocol, bs.nr_addrs, 215 + bs.name_len, bs.name_len, b); 216 + 217 + if (end - b < bs.name_len) 218 + break; 219 + 220 + ret = -EPROTONOSUPPORT; 221 + if (bs.protocol == DNS_SERVER_PROTOCOL_UNSPECIFIED) { 222 + bs.protocol = DNS_SERVER_PROTOCOL_UDP; 223 + } else if (bs.protocol != DNS_SERVER_PROTOCOL_UDP) { 224 + _leave(" = [proto %u]", bs.protocol); 225 + goto error; 226 + } 227 + 228 + if (bs.port == 0) 229 + bs.port = AFS_VL_PORT; 230 + if (bs.source > NR__dns_record_source) 231 + bs.source = NR__dns_record_source; 232 + if (bs.status > NR__dns_lookup_status) 233 + bs.status = NR__dns_lookup_status; 234 + 235 + server = NULL; 236 + if (previous) { 237 + /* See if we can update an old server record */ 238 + for (i = 0; i < previous->nr_servers; i++) { 239 + struct afs_vlserver *p = previous->servers[i].server; 240 + 241 + if (p->name_len == bs.name_len && 242 + p->port == bs.port && 243 + strncasecmp(b, p->name, bs.name_len) == 0) { 244 + server = afs_get_vlserver(p); 245 + break; 246 + } 247 + } 248 + } 249 + 250 + if (!server) { 251 + ret = -ENOMEM; 252 + server = afs_alloc_vlserver(b, bs.name_len, bs.port); 253 + if (!server) 254 + goto error; 255 + } 256 + 257 + b += bs.name_len; 258 + 259 + /* Extract the addresses - note that we can't skip this as we 260 + * have to advance the payload pointer. 261 + */ 262 + addrs = afs_extract_vl_addrs(&b, end, bs.nr_addrs, bs.port); 263 + if (IS_ERR(addrs)) { 264 + ret = PTR_ERR(addrs); 265 + goto error_2; 266 + } 267 + 268 + if (vllist->nr_servers >= nr_servers) { 269 + _debug("skip %u >= %u", vllist->nr_servers, nr_servers); 270 + afs_put_addrlist(addrs); 271 + afs_put_vlserver(cell->net, server); 272 + continue; 273 + } 274 + 275 + addrs->source = bs.source; 276 + addrs->status = bs.status; 277 + 278 + if (addrs->nr_addrs == 0) { 279 + afs_put_addrlist(addrs); 280 + if (!rcu_access_pointer(server->addresses)) { 281 + afs_put_vlserver(cell->net, server); 282 + continue; 283 + } 284 + } else { 285 + struct afs_addr_list *old = addrs; 286 + 287 + write_lock(&server->lock); 288 + rcu_swap_protected(server->addresses, old, 289 + lockdep_is_held(&server->lock)); 290 + write_unlock(&server->lock); 291 + afs_put_addrlist(old); 292 + } 293 + 294 + 295 + /* TODO: Might want to check for duplicates */ 296 + 297 + /* Insertion-sort by priority and weight */ 298 + for (j = 0; j < vllist->nr_servers; j++) { 299 + if (bs.priority < vllist->servers[j].priority) 300 + break; /* Lower preferable */ 301 + if (bs.priority == vllist->servers[j].priority && 302 + bs.weight > vllist->servers[j].weight) 303 + break; /* Higher preferable */ 304 + } 305 + 306 + if (j < vllist->nr_servers) { 307 + memmove(vllist->servers + j + 1, 308 + vllist->servers + j, 309 + (vllist->nr_servers - j) * sizeof(struct afs_vlserver_entry)); 310 + } 311 + 312 + clear_bit(AFS_VLSERVER_FL_PROBED, &server->flags); 313 + 314 + vllist->servers[j].priority = bs.priority; 315 + vllist->servers[j].weight = bs.weight; 316 + vllist->servers[j].server = server; 317 + vllist->nr_servers++; 318 + } 319 + 320 + if (b != end) { 321 + _debug("parse error %zd", b - end); 322 + goto error; 323 + } 324 + 325 + afs_put_vlserverlist(cell->net, previous); 326 + _leave(" = ok [%u]", vllist->nr_servers); 327 + return vllist; 328 + 329 + error_2: 330 + afs_put_vlserver(cell->net, server); 331 + error: 332 + afs_put_vlserverlist(cell->net, vllist); 333 + afs_put_vlserverlist(cell->net, previous); 334 + dump: 335 + if (ret != -ENOMEM) { 336 + printk(KERN_DEBUG "DNS: at %zu\n", (const void *)b - buffer); 337 + print_hex_dump_bytes("DNS: ", DUMP_PREFIX_NONE, buffer, buffer_size); 338 + } 339 + return ERR_PTR(ret); 340 + }
+273
fs/afs/vl_probe.c
··· 1 + /* AFS vlserver probing 2 + * 3 + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/sched.h> 13 + #include <linux/slab.h> 14 + #include "afs_fs.h" 15 + #include "internal.h" 16 + #include "protocol_yfs.h" 17 + 18 + static bool afs_vl_probe_done(struct afs_vlserver *server) 19 + { 20 + if (!atomic_dec_and_test(&server->probe_outstanding)) 21 + return false; 22 + 23 + wake_up_var(&server->probe_outstanding); 24 + clear_bit_unlock(AFS_VLSERVER_FL_PROBING, &server->flags); 25 + wake_up_bit(&server->flags, AFS_VLSERVER_FL_PROBING); 26 + return true; 27 + } 28 + 29 + /* 30 + * Process the result of probing a vlserver. This is called after successful 31 + * or failed delivery of an VL.GetCapabilities operation. 32 + */ 33 + void afs_vlserver_probe_result(struct afs_call *call) 34 + { 35 + struct afs_addr_list *alist = call->alist; 36 + struct afs_vlserver *server = call->reply[0]; 37 + unsigned int server_index = (long)call->reply[1]; 38 + unsigned int index = call->addr_ix; 39 + unsigned int rtt = UINT_MAX; 40 + bool have_result = false; 41 + u64 _rtt; 42 + int ret = call->error; 43 + 44 + _enter("%s,%u,%u,%d,%d", server->name, server_index, index, ret, call->abort_code); 45 + 46 + spin_lock(&server->probe_lock); 47 + 48 + switch (ret) { 49 + case 0: 50 + server->probe.error = 0; 51 + goto responded; 52 + case -ECONNABORTED: 53 + if (!server->probe.responded) { 54 + server->probe.abort_code = call->abort_code; 55 + server->probe.error = ret; 56 + } 57 + goto responded; 58 + case -ENOMEM: 59 + case -ENONET: 60 + server->probe.local_failure = true; 61 + afs_io_error(call, afs_io_error_vl_probe_fail); 62 + goto out; 63 + case -ECONNRESET: /* Responded, but call expired. */ 64 + case -ENETUNREACH: 65 + case -EHOSTUNREACH: 66 + case -ECONNREFUSED: 67 + case -ETIMEDOUT: 68 + case -ETIME: 69 + default: 70 + clear_bit(index, &alist->responded); 71 + set_bit(index, &alist->failed); 72 + if (!server->probe.responded && 73 + (server->probe.error == 0 || 74 + server->probe.error == -ETIMEDOUT || 75 + server->probe.error == -ETIME)) 76 + server->probe.error = ret; 77 + afs_io_error(call, afs_io_error_vl_probe_fail); 78 + goto out; 79 + } 80 + 81 + responded: 82 + set_bit(index, &alist->responded); 83 + clear_bit(index, &alist->failed); 84 + 85 + if (call->service_id == YFS_VL_SERVICE) { 86 + server->probe.is_yfs = true; 87 + set_bit(AFS_VLSERVER_FL_IS_YFS, &server->flags); 88 + alist->addrs[index].srx_service = call->service_id; 89 + } else { 90 + server->probe.not_yfs = true; 91 + if (!server->probe.is_yfs) { 92 + clear_bit(AFS_VLSERVER_FL_IS_YFS, &server->flags); 93 + alist->addrs[index].srx_service = call->service_id; 94 + } 95 + } 96 + 97 + /* Get the RTT and scale it to fit into a 32-bit value that represents 98 + * over a minute of time so that we can access it with one instruction 99 + * on a 32-bit system. 100 + */ 101 + _rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); 102 + _rtt /= 64; 103 + rtt = (_rtt > UINT_MAX) ? UINT_MAX : _rtt; 104 + if (rtt < server->probe.rtt) { 105 + server->probe.rtt = rtt; 106 + alist->preferred = index; 107 + have_result = true; 108 + } 109 + 110 + smp_wmb(); /* Set rtt before responded. */ 111 + server->probe.responded = true; 112 + set_bit(AFS_VLSERVER_FL_PROBED, &server->flags); 113 + out: 114 + spin_unlock(&server->probe_lock); 115 + 116 + _debug("probe [%u][%u] %pISpc rtt=%u ret=%d", 117 + server_index, index, &alist->addrs[index].transport, 118 + (unsigned int)rtt, ret); 119 + 120 + have_result |= afs_vl_probe_done(server); 121 + if (have_result) { 122 + server->probe.have_result = true; 123 + wake_up_var(&server->probe.have_result); 124 + wake_up_all(&server->probe_wq); 125 + } 126 + } 127 + 128 + /* 129 + * Probe all of a vlserver's addresses to find out the best route and to 130 + * query its capabilities. 131 + */ 132 + static int afs_do_probe_vlserver(struct afs_net *net, 133 + struct afs_vlserver *server, 134 + struct key *key, 135 + unsigned int server_index) 136 + { 137 + struct afs_addr_cursor ac = { 138 + .index = 0, 139 + }; 140 + int ret; 141 + 142 + _enter("%s", server->name); 143 + 144 + read_lock(&server->lock); 145 + ac.alist = rcu_dereference_protected(server->addresses, 146 + lockdep_is_held(&server->lock)); 147 + read_unlock(&server->lock); 148 + 149 + atomic_set(&server->probe_outstanding, ac.alist->nr_addrs); 150 + memset(&server->probe, 0, sizeof(server->probe)); 151 + server->probe.rtt = UINT_MAX; 152 + 153 + for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { 154 + ret = afs_vl_get_capabilities(net, &ac, key, server, 155 + server_index, true); 156 + if (ret != -EINPROGRESS) { 157 + afs_vl_probe_done(server); 158 + return ret; 159 + } 160 + } 161 + 162 + return 0; 163 + } 164 + 165 + /* 166 + * Send off probes to all unprobed servers. 167 + */ 168 + int afs_send_vl_probes(struct afs_net *net, struct key *key, 169 + struct afs_vlserver_list *vllist) 170 + { 171 + struct afs_vlserver *server; 172 + int i, ret; 173 + 174 + for (i = 0; i < vllist->nr_servers; i++) { 175 + server = vllist->servers[i].server; 176 + if (test_bit(AFS_VLSERVER_FL_PROBED, &server->flags)) 177 + continue; 178 + 179 + if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags)) { 180 + ret = afs_do_probe_vlserver(net, server, key, i); 181 + if (ret) 182 + return ret; 183 + } 184 + } 185 + 186 + return 0; 187 + } 188 + 189 + /* 190 + * Wait for the first as-yet untried server to respond. 191 + */ 192 + int afs_wait_for_vl_probes(struct afs_vlserver_list *vllist, 193 + unsigned long untried) 194 + { 195 + struct wait_queue_entry *waits; 196 + struct afs_vlserver *server; 197 + unsigned int rtt = UINT_MAX; 198 + bool have_responders = false; 199 + int pref = -1, i; 200 + 201 + _enter("%u,%lx", vllist->nr_servers, untried); 202 + 203 + /* Only wait for servers that have a probe outstanding. */ 204 + for (i = 0; i < vllist->nr_servers; i++) { 205 + if (test_bit(i, &untried)) { 206 + server = vllist->servers[i].server; 207 + if (!test_bit(AFS_VLSERVER_FL_PROBING, &server->flags)) 208 + __clear_bit(i, &untried); 209 + if (server->probe.responded) 210 + have_responders = true; 211 + } 212 + } 213 + if (have_responders || !untried) 214 + return 0; 215 + 216 + waits = kmalloc(array_size(vllist->nr_servers, sizeof(*waits)), GFP_KERNEL); 217 + if (!waits) 218 + return -ENOMEM; 219 + 220 + for (i = 0; i < vllist->nr_servers; i++) { 221 + if (test_bit(i, &untried)) { 222 + server = vllist->servers[i].server; 223 + init_waitqueue_entry(&waits[i], current); 224 + add_wait_queue(&server->probe_wq, &waits[i]); 225 + } 226 + } 227 + 228 + for (;;) { 229 + bool still_probing = false; 230 + 231 + set_current_state(TASK_INTERRUPTIBLE); 232 + for (i = 0; i < vllist->nr_servers; i++) { 233 + if (test_bit(i, &untried)) { 234 + server = vllist->servers[i].server; 235 + if (server->probe.responded) 236 + goto stop; 237 + if (test_bit(AFS_VLSERVER_FL_PROBING, &server->flags)) 238 + still_probing = true; 239 + } 240 + } 241 + 242 + if (!still_probing || unlikely(signal_pending(current))) 243 + goto stop; 244 + schedule(); 245 + } 246 + 247 + stop: 248 + set_current_state(TASK_RUNNING); 249 + 250 + for (i = 0; i < vllist->nr_servers; i++) { 251 + if (test_bit(i, &untried)) { 252 + server = vllist->servers[i].server; 253 + if (server->probe.responded && 254 + server->probe.rtt < rtt) { 255 + pref = i; 256 + rtt = server->probe.rtt; 257 + } 258 + 259 + remove_wait_queue(&server->probe_wq, &waits[i]); 260 + } 261 + } 262 + 263 + kfree(waits); 264 + 265 + if (pref == -1 && signal_pending(current)) 266 + return -ERESTARTSYS; 267 + 268 + if (pref >= 0) 269 + vllist->preferred = pref; 270 + 271 + _leave(" = 0 [%u]", pref); 272 + return 0; 273 + }
+355
fs/afs/vl_rotate.c
··· 1 + /* Handle vlserver selection and rotation. 2 + * 3 + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/kernel.h> 13 + #include <linux/sched.h> 14 + #include <linux/sched/signal.h> 15 + #include "internal.h" 16 + #include "afs_vl.h" 17 + 18 + /* 19 + * Begin an operation on a volume location server. 20 + */ 21 + bool afs_begin_vlserver_operation(struct afs_vl_cursor *vc, struct afs_cell *cell, 22 + struct key *key) 23 + { 24 + memset(vc, 0, sizeof(*vc)); 25 + vc->cell = cell; 26 + vc->key = key; 27 + vc->error = -EDESTADDRREQ; 28 + vc->ac.error = SHRT_MAX; 29 + 30 + if (signal_pending(current)) { 31 + vc->error = -EINTR; 32 + vc->flags |= AFS_VL_CURSOR_STOP; 33 + return false; 34 + } 35 + 36 + return true; 37 + } 38 + 39 + /* 40 + * Begin iteration through a server list, starting with the last used server if 41 + * possible, or the last recorded good server if not. 42 + */ 43 + static bool afs_start_vl_iteration(struct afs_vl_cursor *vc) 44 + { 45 + struct afs_cell *cell = vc->cell; 46 + 47 + if (wait_on_bit(&cell->flags, AFS_CELL_FL_NO_LOOKUP_YET, 48 + TASK_INTERRUPTIBLE)) { 49 + vc->error = -ERESTARTSYS; 50 + return false; 51 + } 52 + 53 + read_lock(&cell->vl_servers_lock); 54 + vc->server_list = afs_get_vlserverlist( 55 + rcu_dereference_protected(cell->vl_servers, 56 + lockdep_is_held(&cell->vl_servers_lock))); 57 + read_unlock(&cell->vl_servers_lock); 58 + if (!vc->server_list || !vc->server_list->nr_servers) 59 + return false; 60 + 61 + vc->untried = (1UL << vc->server_list->nr_servers) - 1; 62 + vc->index = -1; 63 + return true; 64 + } 65 + 66 + /* 67 + * Select the vlserver to use. May be called multiple times to rotate 68 + * through the vlservers. 69 + */ 70 + bool afs_select_vlserver(struct afs_vl_cursor *vc) 71 + { 72 + struct afs_addr_list *alist; 73 + struct afs_vlserver *vlserver; 74 + u32 rtt; 75 + int error = vc->ac.error, abort_code, i; 76 + 77 + _enter("%lx[%d],%lx[%d],%d,%d", 78 + vc->untried, vc->index, 79 + vc->ac.tried, vc->ac.index, 80 + error, vc->ac.abort_code); 81 + 82 + if (vc->flags & AFS_VL_CURSOR_STOP) { 83 + _leave(" = f [stopped]"); 84 + return false; 85 + } 86 + 87 + vc->nr_iterations++; 88 + 89 + /* Evaluate the result of the previous operation, if there was one. */ 90 + switch (error) { 91 + case SHRT_MAX: 92 + goto start; 93 + 94 + default: 95 + case 0: 96 + /* Success or local failure. Stop. */ 97 + vc->error = error; 98 + vc->flags |= AFS_VL_CURSOR_STOP; 99 + _leave(" = f [okay/local %d]", vc->ac.error); 100 + return false; 101 + 102 + case -ECONNABORTED: 103 + /* The far side rejected the operation on some grounds. This 104 + * might involve the server being busy or the volume having been moved. 105 + */ 106 + switch (vc->ac.abort_code) { 107 + case AFSVL_IO: 108 + case AFSVL_BADVOLOPER: 109 + case AFSVL_NOMEM: 110 + /* The server went weird. */ 111 + vc->error = -EREMOTEIO; 112 + //write_lock(&vc->cell->vl_servers_lock); 113 + //vc->server_list->weird_mask |= 1 << vc->index; 114 + //write_unlock(&vc->cell->vl_servers_lock); 115 + goto next_server; 116 + 117 + default: 118 + vc->error = afs_abort_to_error(vc->ac.abort_code); 119 + goto failed; 120 + } 121 + 122 + case -ENETUNREACH: 123 + case -EHOSTUNREACH: 124 + case -ECONNREFUSED: 125 + case -ETIMEDOUT: 126 + case -ETIME: 127 + _debug("no conn %d", error); 128 + vc->error = error; 129 + goto iterate_address; 130 + 131 + case -ECONNRESET: 132 + _debug("call reset"); 133 + vc->error = error; 134 + vc->flags |= AFS_VL_CURSOR_RETRY; 135 + goto next_server; 136 + } 137 + 138 + restart_from_beginning: 139 + _debug("restart"); 140 + afs_end_cursor(&vc->ac); 141 + afs_put_vlserverlist(vc->cell->net, vc->server_list); 142 + vc->server_list = NULL; 143 + if (vc->flags & AFS_VL_CURSOR_RETRIED) 144 + goto failed; 145 + vc->flags |= AFS_VL_CURSOR_RETRIED; 146 + start: 147 + _debug("start"); 148 + 149 + if (!afs_start_vl_iteration(vc)) 150 + goto failed; 151 + 152 + error = afs_send_vl_probes(vc->cell->net, vc->key, vc->server_list); 153 + if (error < 0) 154 + goto failed_set_error; 155 + 156 + pick_server: 157 + _debug("pick [%lx]", vc->untried); 158 + 159 + error = afs_wait_for_vl_probes(vc->server_list, vc->untried); 160 + if (error < 0) 161 + goto failed_set_error; 162 + 163 + /* Pick the untried server with the lowest RTT. */ 164 + vc->index = vc->server_list->preferred; 165 + if (test_bit(vc->index, &vc->untried)) 166 + goto selected_server; 167 + 168 + vc->index = -1; 169 + rtt = U32_MAX; 170 + for (i = 0; i < vc->server_list->nr_servers; i++) { 171 + struct afs_vlserver *s = vc->server_list->servers[i].server; 172 + 173 + if (!test_bit(i, &vc->untried) || !s->probe.responded) 174 + continue; 175 + if (s->probe.rtt < rtt) { 176 + vc->index = i; 177 + rtt = s->probe.rtt; 178 + } 179 + } 180 + 181 + if (vc->index == -1) 182 + goto no_more_servers; 183 + 184 + selected_server: 185 + _debug("use %d", vc->index); 186 + __clear_bit(vc->index, &vc->untried); 187 + 188 + /* We're starting on a different vlserver from the list. We need to 189 + * check it, find its address list and probe its capabilities before we 190 + * use it. 191 + */ 192 + ASSERTCMP(vc->ac.alist, ==, NULL); 193 + vlserver = vc->server_list->servers[vc->index].server; 194 + vc->server = vlserver; 195 + 196 + _debug("USING VLSERVER: %s", vlserver->name); 197 + 198 + read_lock(&vlserver->lock); 199 + alist = rcu_dereference_protected(vlserver->addresses, 200 + lockdep_is_held(&vlserver->lock)); 201 + afs_get_addrlist(alist); 202 + read_unlock(&vlserver->lock); 203 + 204 + memset(&vc->ac, 0, sizeof(vc->ac)); 205 + 206 + if (!vc->ac.alist) 207 + vc->ac.alist = alist; 208 + else 209 + afs_put_addrlist(alist); 210 + 211 + vc->ac.index = -1; 212 + 213 + iterate_address: 214 + ASSERT(vc->ac.alist); 215 + /* Iterate over the current server's address list to try and find an 216 + * address on which it will respond to us. 217 + */ 218 + if (!afs_iterate_addresses(&vc->ac)) 219 + goto next_server; 220 + 221 + _debug("VL address %d/%d", vc->ac.index, vc->ac.alist->nr_addrs); 222 + 223 + _leave(" = t %pISpc", &vc->ac.alist->addrs[vc->ac.index].transport); 224 + return true; 225 + 226 + next_server: 227 + _debug("next"); 228 + afs_end_cursor(&vc->ac); 229 + goto pick_server; 230 + 231 + no_more_servers: 232 + /* That's all the servers poked to no good effect. Try again if some 233 + * of them were busy. 234 + */ 235 + if (vc->flags & AFS_VL_CURSOR_RETRY) 236 + goto restart_from_beginning; 237 + 238 + abort_code = 0; 239 + error = -EDESTADDRREQ; 240 + for (i = 0; i < vc->server_list->nr_servers; i++) { 241 + struct afs_vlserver *s = vc->server_list->servers[i].server; 242 + int probe_error = READ_ONCE(s->probe.error); 243 + 244 + switch (probe_error) { 245 + case 0: 246 + continue; 247 + default: 248 + if (error == -ETIMEDOUT || 249 + error == -ETIME) 250 + continue; 251 + case -ETIMEDOUT: 252 + case -ETIME: 253 + if (error == -ENOMEM || 254 + error == -ENONET) 255 + continue; 256 + case -ENOMEM: 257 + case -ENONET: 258 + if (error == -ENETUNREACH) 259 + continue; 260 + case -ENETUNREACH: 261 + if (error == -EHOSTUNREACH) 262 + continue; 263 + case -EHOSTUNREACH: 264 + if (error == -ECONNREFUSED) 265 + continue; 266 + case -ECONNREFUSED: 267 + if (error == -ECONNRESET) 268 + continue; 269 + case -ECONNRESET: /* Responded, but call expired. */ 270 + if (error == -ECONNABORTED) 271 + continue; 272 + case -ECONNABORTED: 273 + abort_code = s->probe.abort_code; 274 + error = probe_error; 275 + continue; 276 + } 277 + } 278 + 279 + if (error == -ECONNABORTED) 280 + error = afs_abort_to_error(abort_code); 281 + 282 + failed_set_error: 283 + vc->error = error; 284 + failed: 285 + vc->flags |= AFS_VL_CURSOR_STOP; 286 + afs_end_cursor(&vc->ac); 287 + _leave(" = f [failed %d]", vc->error); 288 + return false; 289 + } 290 + 291 + /* 292 + * Dump cursor state in the case of the error being EDESTADDRREQ. 293 + */ 294 + static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc) 295 + { 296 + static int count; 297 + int i; 298 + 299 + if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3) 300 + return; 301 + count++; 302 + 303 + rcu_read_lock(); 304 + pr_notice("EDESTADDR occurred\n"); 305 + pr_notice("VC: ut=%lx ix=%u ni=%hu fl=%hx err=%hd\n", 306 + vc->untried, vc->index, vc->nr_iterations, vc->flags, vc->error); 307 + 308 + if (vc->server_list) { 309 + const struct afs_vlserver_list *sl = vc->server_list; 310 + pr_notice("VC: SL nr=%u ix=%u\n", 311 + sl->nr_servers, sl->index); 312 + for (i = 0; i < sl->nr_servers; i++) { 313 + const struct afs_vlserver *s = sl->servers[i].server; 314 + pr_notice("VC: server %s+%hu fl=%lx E=%hd\n", 315 + s->name, s->port, s->flags, s->probe.error); 316 + if (s->addresses) { 317 + const struct afs_addr_list *a = 318 + rcu_dereference(s->addresses); 319 + pr_notice("VC: - nr=%u/%u/%u pf=%u\n", 320 + a->nr_ipv4, a->nr_addrs, a->max_addrs, 321 + a->preferred); 322 + pr_notice("VC: - pr=%lx R=%lx F=%lx\n", 323 + a->probed, a->responded, a->failed); 324 + if (a == vc->ac.alist) 325 + pr_notice("VC: - current\n"); 326 + } 327 + } 328 + } 329 + 330 + pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n", 331 + vc->ac.tried, vc->ac.index, vc->ac.abort_code, vc->ac.error, 332 + vc->ac.responded, vc->ac.nr_iterations); 333 + rcu_read_unlock(); 334 + } 335 + 336 + /* 337 + * Tidy up a volume location server cursor and unlock the vnode. 338 + */ 339 + int afs_end_vlserver_operation(struct afs_vl_cursor *vc) 340 + { 341 + struct afs_net *net = vc->cell->net; 342 + 343 + if (vc->error == -EDESTADDRREQ || 344 + vc->error == -ENETUNREACH || 345 + vc->error == -EHOSTUNREACH) 346 + afs_vl_dump_edestaddrreq(vc); 347 + 348 + afs_end_cursor(&vc->ac); 349 + afs_put_vlserverlist(net, vc->server_list); 350 + 351 + if (vc->error == -ECONNABORTED) 352 + vc->error = afs_abort_to_error(vc->ac.abort_code); 353 + 354 + return vc->error; 355 + }
+98 -97
fs/afs/vlclient.c
··· 128 128 * Dispatch a get volume entry by name or ID operation (uuid variant). If the 129 129 * volname is a decimal number then it's a volume ID not a volume name. 130 130 */ 131 - struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_net *net, 132 - struct afs_addr_cursor *ac, 133 - struct key *key, 131 + struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc, 134 132 const char *volname, 135 133 int volnamesz) 136 134 { 137 135 struct afs_vldb_entry *entry; 138 136 struct afs_call *call; 137 + struct afs_net *net = vc->cell->net; 139 138 size_t reqsz, padsz; 140 139 __be32 *bp; 141 140 ··· 154 155 return ERR_PTR(-ENOMEM); 155 156 } 156 157 157 - call->key = key; 158 + call->key = vc->key; 158 159 call->reply[0] = entry; 159 160 call->ret_reply0 = true; 160 161 ··· 167 168 memset((void *)bp + volnamesz, 0, padsz); 168 169 169 170 trace_afs_make_vl_call(call); 170 - return (struct afs_vldb_entry *)afs_make_call(ac, call, GFP_KERNEL, false); 171 + return (struct afs_vldb_entry *)afs_make_call(&vc->ac, call, GFP_KERNEL, false); 171 172 } 172 173 173 174 /* ··· 186 187 u32 uniquifier, nentries, count; 187 188 int i, ret; 188 189 189 - _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count); 190 + _enter("{%u,%zu/%u}", 191 + call->unmarshall, iov_iter_count(call->_iter), call->count); 190 192 191 - again: 192 193 switch (call->unmarshall) { 193 194 case 0: 194 - call->offset = 0; 195 + afs_extract_to_buf(call, 196 + sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32)); 195 197 call->unmarshall++; 196 198 197 199 /* Extract the returned uuid, uniquifier, nentries and blkaddrs size */ 198 200 case 1: 199 - ret = afs_extract_data(call, call->buffer, 200 - sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32), 201 - true); 201 + ret = afs_extract_data(call, true); 202 202 if (ret < 0) 203 203 return ret; 204 204 ··· 214 216 call->reply[0] = alist; 215 217 call->count = count; 216 218 call->count2 = nentries; 217 - call->offset = 0; 218 219 call->unmarshall++; 220 + 221 + more_entries: 222 + count = min(call->count, 4U); 223 + afs_extract_to_buf(call, count * sizeof(__be32)); 219 224 220 225 /* Extract entries */ 221 226 case 2: 222 - count = min(call->count, 4U); 223 - ret = afs_extract_data(call, call->buffer, 224 - count * sizeof(__be32), 225 - call->count > 4); 227 + ret = afs_extract_data(call, call->count > 4); 226 228 if (ret < 0) 227 229 return ret; 228 230 229 231 alist = call->reply[0]; 230 232 bp = call->buffer; 233 + count = min(call->count, 4U); 231 234 for (i = 0; i < count; i++) 232 235 if (alist->nr_addrs < call->count2) 233 236 afs_merge_fs_addr4(alist, *bp++, AFS_FS_PORT); 234 237 235 238 call->count -= count; 236 239 if (call->count > 0) 237 - goto again; 238 - call->offset = 0; 240 + goto more_entries; 239 241 call->unmarshall++; 240 242 break; 241 243 } ··· 265 267 * Dispatch an operation to get the addresses for a server, where the server is 266 268 * nominated by UUID. 267 269 */ 268 - struct afs_addr_list *afs_vl_get_addrs_u(struct afs_net *net, 269 - struct afs_addr_cursor *ac, 270 - struct key *key, 270 + struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc, 271 271 const uuid_t *uuid) 272 272 { 273 273 struct afs_ListAddrByAttributes__xdr *r; 274 274 const struct afs_uuid *u = (const struct afs_uuid *)uuid; 275 275 struct afs_call *call; 276 + struct afs_net *net = vc->cell->net; 276 277 __be32 *bp; 277 278 int i; 278 279 ··· 283 286 if (!call) 284 287 return ERR_PTR(-ENOMEM); 285 288 286 - call->key = key; 289 + call->key = vc->key; 287 290 call->reply[0] = NULL; 288 291 call->ret_reply0 = true; 289 292 ··· 304 307 r->uuid.node[i] = htonl(u->node[i]); 305 308 306 309 trace_afs_make_vl_call(call); 307 - return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false); 310 + return (struct afs_addr_list *)afs_make_call(&vc->ac, call, GFP_KERNEL, false); 308 311 } 309 312 310 313 /* ··· 315 318 u32 count; 316 319 int ret; 317 320 318 - _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count); 321 + _enter("{%u,%zu/%u}", 322 + call->unmarshall, iov_iter_count(call->_iter), call->count); 319 323 320 - again: 321 324 switch (call->unmarshall) { 322 325 case 0: 323 - call->offset = 0; 326 + afs_extract_to_tmp(call); 324 327 call->unmarshall++; 325 328 326 329 /* Extract the capabilities word count */ 327 330 case 1: 328 - ret = afs_extract_data(call, &call->tmp, 329 - 1 * sizeof(__be32), 330 - true); 331 + ret = afs_extract_data(call, true); 331 332 if (ret < 0) 332 333 return ret; 333 334 334 335 count = ntohl(call->tmp); 335 - 336 336 call->count = count; 337 337 call->count2 = count; 338 - call->offset = 0; 338 + 339 339 call->unmarshall++; 340 + afs_extract_discard(call, count * sizeof(__be32)); 340 341 341 342 /* Extract capabilities words */ 342 343 case 2: 343 - count = min(call->count, 16U); 344 - ret = afs_extract_data(call, call->buffer, 345 - count * sizeof(__be32), 346 - call->count > 16); 344 + ret = afs_extract_data(call, false); 347 345 if (ret < 0) 348 346 return ret; 349 347 350 348 /* TODO: Examine capabilities */ 351 349 352 - call->count -= count; 353 - if (call->count > 0) 354 - goto again; 355 - call->offset = 0; 356 350 call->unmarshall++; 357 351 break; 358 352 } 359 353 360 - call->reply[0] = (void *)(unsigned long)call->service_id; 361 - 362 354 _leave(" = 0 [done]"); 363 355 return 0; 356 + } 357 + 358 + static void afs_destroy_vl_get_capabilities(struct afs_call *call) 359 + { 360 + struct afs_vlserver *server = call->reply[0]; 361 + 362 + afs_put_vlserver(call->net, server); 363 + afs_flat_call_destructor(call); 364 364 } 365 365 366 366 /* ··· 367 373 .name = "VL.GetCapabilities", 368 374 .op = afs_VL_GetCapabilities, 369 375 .deliver = afs_deliver_vl_get_capabilities, 370 - .destructor = afs_flat_call_destructor, 376 + .done = afs_vlserver_probe_result, 377 + .destructor = afs_destroy_vl_get_capabilities, 371 378 }; 372 379 373 380 /* 374 - * Probe a fileserver for the capabilities that it supports. This can 381 + * Probe a volume server for the capabilities that it supports. This can 375 382 * return up to 196 words. 376 383 * 377 384 * We use this to probe for service upgrade to determine what the server at the ··· 380 385 */ 381 386 int afs_vl_get_capabilities(struct afs_net *net, 382 387 struct afs_addr_cursor *ac, 383 - struct key *key) 388 + struct key *key, 389 + struct afs_vlserver *server, 390 + unsigned int server_index, 391 + bool async) 384 392 { 385 393 struct afs_call *call; 386 394 __be32 *bp; ··· 395 397 return -ENOMEM; 396 398 397 399 call->key = key; 398 - call->upgrade = true; /* Let's see if this is a YFS server */ 399 - call->reply[0] = (void *)VLGETCAPABILITIES; 400 - call->ret_reply0 = true; 400 + call->reply[0] = afs_get_vlserver(server); 401 + call->reply[1] = (void *)(long)server_index; 402 + call->upgrade = true; 403 + call->want_reply_time = true; 401 404 402 405 /* marshall the parameters */ 403 406 bp = call->request; ··· 406 407 407 408 /* Can't take a ref on server */ 408 409 trace_afs_make_vl_call(call); 409 - return afs_make_call(ac, call, GFP_KERNEL, false); 410 + return afs_make_call(ac, call, GFP_KERNEL, async); 410 411 } 411 412 412 413 /* ··· 425 426 u32 uniquifier, size; 426 427 int ret; 427 428 428 - _enter("{%u,%zu/%u,%u}", call->unmarshall, call->offset, call->count, call->count2); 429 + _enter("{%u,%zu,%u}", 430 + call->unmarshall, iov_iter_count(call->_iter), call->count2); 429 431 430 - again: 431 432 switch (call->unmarshall) { 432 433 case 0: 433 - call->offset = 0; 434 + afs_extract_to_buf(call, sizeof(uuid_t) + 3 * sizeof(__be32)); 434 435 call->unmarshall = 1; 435 436 436 437 /* Extract the returned uuid, uniquifier, fsEndpoints count and 437 438 * either the first fsEndpoint type or the volEndpoints 438 439 * count if there are no fsEndpoints. */ 439 440 case 1: 440 - ret = afs_extract_data(call, call->buffer, 441 - sizeof(uuid_t) + 442 - 3 * sizeof(__be32), 443 - true); 441 + ret = afs_extract_data(call, true); 444 442 if (ret < 0) 445 443 return ret; 446 444 ··· 447 451 call->count2 = ntohl(*bp); /* Type or next count */ 448 452 449 453 if (call->count > YFS_MAXENDPOINTS) 450 - return afs_protocol_error(call, -EBADMSG); 454 + return afs_protocol_error(call, -EBADMSG, 455 + afs_eproto_yvl_fsendpt_num); 451 456 452 457 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT); 453 458 if (!alist) 454 459 return -ENOMEM; 455 460 alist->version = uniquifier; 456 461 call->reply[0] = alist; 457 - call->offset = 0; 458 462 459 463 if (call->count == 0) 460 464 goto extract_volendpoints; 461 465 462 - call->unmarshall = 2; 463 - 464 - /* Extract fsEndpoints[] entries */ 465 - case 2: 466 + next_fsendpoint: 466 467 switch (call->count2) { 467 468 case YFS_ENDPOINT_IPV4: 468 469 size = sizeof(__be32) * (1 + 1 + 1); ··· 468 475 size = sizeof(__be32) * (1 + 4 + 1); 469 476 break; 470 477 default: 471 - return afs_protocol_error(call, -EBADMSG); 478 + return afs_protocol_error(call, -EBADMSG, 479 + afs_eproto_yvl_fsendpt_type); 472 480 } 473 481 474 482 size += sizeof(__be32); 475 - ret = afs_extract_data(call, call->buffer, size, true); 483 + afs_extract_to_buf(call, size); 484 + call->unmarshall = 2; 485 + 486 + /* Extract fsEndpoints[] entries */ 487 + case 2: 488 + ret = afs_extract_data(call, true); 476 489 if (ret < 0) 477 490 return ret; 478 491 ··· 487 488 switch (call->count2) { 488 489 case YFS_ENDPOINT_IPV4: 489 490 if (ntohl(bp[0]) != sizeof(__be32) * 2) 490 - return afs_protocol_error(call, -EBADMSG); 491 + return afs_protocol_error(call, -EBADMSG, 492 + afs_eproto_yvl_fsendpt4_len); 491 493 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2])); 492 494 bp += 3; 493 495 break; 494 496 case YFS_ENDPOINT_IPV6: 495 497 if (ntohl(bp[0]) != sizeof(__be32) * 5) 496 - return afs_protocol_error(call, -EBADMSG); 498 + return afs_protocol_error(call, -EBADMSG, 499 + afs_eproto_yvl_fsendpt6_len); 497 500 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5])); 498 501 bp += 6; 499 502 break; 500 503 default: 501 - return afs_protocol_error(call, -EBADMSG); 504 + return afs_protocol_error(call, -EBADMSG, 505 + afs_eproto_yvl_fsendpt_type); 502 506 } 503 507 504 508 /* Got either the type of the next entry or the count of ··· 509 507 */ 510 508 call->count2 = ntohl(*bp++); 511 509 512 - call->offset = 0; 513 510 call->count--; 514 511 if (call->count > 0) 515 - goto again; 512 + goto next_fsendpoint; 516 513 517 514 extract_volendpoints: 518 515 /* Extract the list of volEndpoints. */ ··· 519 518 if (!call->count) 520 519 goto end; 521 520 if (call->count > YFS_MAXENDPOINTS) 522 - return afs_protocol_error(call, -EBADMSG); 521 + return afs_protocol_error(call, -EBADMSG, 522 + afs_eproto_yvl_vlendpt_type); 523 523 524 + afs_extract_to_buf(call, 1 * sizeof(__be32)); 524 525 call->unmarshall = 3; 525 526 526 527 /* Extract the type of volEndpoints[0]. Normally we would ··· 530 527 * data of the current one, but this is the first... 531 528 */ 532 529 case 3: 533 - ret = afs_extract_data(call, call->buffer, sizeof(__be32), true); 530 + ret = afs_extract_data(call, true); 534 531 if (ret < 0) 535 532 return ret; 536 533 537 534 bp = call->buffer; 538 - call->count2 = ntohl(*bp++); 539 - call->offset = 0; 540 - call->unmarshall = 4; 541 535 542 - /* Extract volEndpoints[] entries */ 543 - case 4: 536 + next_volendpoint: 537 + call->count2 = ntohl(*bp++); 544 538 switch (call->count2) { 545 539 case YFS_ENDPOINT_IPV4: 546 540 size = sizeof(__be32) * (1 + 1 + 1); ··· 546 546 size = sizeof(__be32) * (1 + 4 + 1); 547 547 break; 548 548 default: 549 - return afs_protocol_error(call, -EBADMSG); 549 + return afs_protocol_error(call, -EBADMSG, 550 + afs_eproto_yvl_vlendpt_type); 550 551 } 551 552 552 553 if (call->count > 1) 553 - size += sizeof(__be32); 554 - ret = afs_extract_data(call, call->buffer, size, true); 554 + size += sizeof(__be32); /* Get next type too */ 555 + afs_extract_to_buf(call, size); 556 + call->unmarshall = 4; 557 + 558 + /* Extract volEndpoints[] entries */ 559 + case 4: 560 + ret = afs_extract_data(call, true); 555 561 if (ret < 0) 556 562 return ret; 557 563 ··· 565 559 switch (call->count2) { 566 560 case YFS_ENDPOINT_IPV4: 567 561 if (ntohl(bp[0]) != sizeof(__be32) * 2) 568 - return afs_protocol_error(call, -EBADMSG); 562 + return afs_protocol_error(call, -EBADMSG, 563 + afs_eproto_yvl_vlendpt4_len); 569 564 bp += 3; 570 565 break; 571 566 case YFS_ENDPOINT_IPV6: 572 567 if (ntohl(bp[0]) != sizeof(__be32) * 5) 573 - return afs_protocol_error(call, -EBADMSG); 568 + return afs_protocol_error(call, -EBADMSG, 569 + afs_eproto_yvl_vlendpt6_len); 574 570 bp += 6; 575 571 break; 576 572 default: 577 - return afs_protocol_error(call, -EBADMSG); 573 + return afs_protocol_error(call, -EBADMSG, 574 + afs_eproto_yvl_vlendpt_type); 578 575 } 579 576 580 577 /* Got either the type of the next entry or the count of 581 578 * volEndpoints if no more fsEndpoints. 582 579 */ 583 - call->offset = 0; 584 580 call->count--; 585 - if (call->count > 0) { 586 - call->count2 = ntohl(*bp++); 587 - goto again; 588 - } 581 + if (call->count > 0) 582 + goto next_volendpoint; 589 583 590 584 end: 585 + afs_extract_discard(call, 0); 591 586 call->unmarshall = 5; 592 587 593 588 /* Done */ 594 589 case 5: 595 - ret = afs_extract_data(call, call->buffer, 0, false); 590 + ret = afs_extract_data(call, false); 596 591 if (ret < 0) 597 592 return ret; 598 593 call->unmarshall = 6; ··· 603 596 } 604 597 605 598 alist = call->reply[0]; 606 - 607 - /* Start with IPv6 if available. */ 608 - if (alist->nr_ipv4 < alist->nr_addrs) 609 - alist->index = alist->nr_ipv4; 610 - 611 599 _leave(" = 0 [done]"); 612 600 return 0; 613 601 } ··· 621 619 * Dispatch an operation to get the addresses for a server, where the server is 622 620 * nominated by UUID. 623 621 */ 624 - struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_net *net, 625 - struct afs_addr_cursor *ac, 626 - struct key *key, 622 + struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc, 627 623 const uuid_t *uuid) 628 624 { 629 625 struct afs_call *call; 626 + struct afs_net *net = vc->cell->net; 630 627 __be32 *bp; 631 628 632 629 _enter(""); ··· 636 635 if (!call) 637 636 return ERR_PTR(-ENOMEM); 638 637 639 - call->key = key; 638 + call->key = vc->key; 640 639 call->reply[0] = NULL; 641 640 call->ret_reply0 = true; 642 641 ··· 647 646 memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */ 648 647 649 648 trace_afs_make_vl_call(call); 650 - return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false); 649 + return (struct afs_addr_list *)afs_make_call(&vc->ac, call, GFP_KERNEL, false); 651 650 }
+9 -45
fs/afs/volume.c
··· 74 74 const char *volname, 75 75 size_t volnamesz) 76 76 { 77 - struct afs_addr_cursor ac; 78 - struct afs_vldb_entry *vldb; 77 + struct afs_vldb_entry *vldb = ERR_PTR(-EDESTADDRREQ); 78 + struct afs_vl_cursor vc; 79 79 int ret; 80 80 81 - ret = afs_set_vl_cursor(&ac, cell); 82 - if (ret < 0) 83 - return ERR_PTR(ret); 81 + if (!afs_begin_vlserver_operation(&vc, cell, key)) 82 + return ERR_PTR(-ERESTARTSYS); 84 83 85 - while (afs_iterate_addresses(&ac)) { 86 - if (!test_bit(ac.index, &ac.alist->probed)) { 87 - ret = afs_vl_get_capabilities(cell->net, &ac, key); 88 - switch (ret) { 89 - case VL_SERVICE: 90 - clear_bit(ac.index, &ac.alist->yfs); 91 - set_bit(ac.index, &ac.alist->probed); 92 - ac.addr->srx_service = ret; 93 - break; 94 - case YFS_VL_SERVICE: 95 - set_bit(ac.index, &ac.alist->yfs); 96 - set_bit(ac.index, &ac.alist->probed); 97 - ac.addr->srx_service = ret; 98 - break; 99 - } 100 - } 101 - 102 - vldb = afs_vl_get_entry_by_name_u(cell->net, &ac, key, 103 - volname, volnamesz); 104 - switch (ac.error) { 105 - case 0: 106 - afs_end_cursor(&ac); 107 - return vldb; 108 - case -ECONNABORTED: 109 - ac.error = afs_abort_to_error(ac.abort_code); 110 - goto error; 111 - case -ENOMEM: 112 - case -ENONET: 113 - goto error; 114 - case -ENETUNREACH: 115 - case -EHOSTUNREACH: 116 - case -ECONNREFUSED: 117 - break; 118 - default: 119 - ac.error = -EIO; 120 - goto error; 121 - } 84 + while (afs_select_vlserver(&vc)) { 85 + vldb = afs_vl_get_entry_by_name_u(&vc, volname, volnamesz); 122 86 } 123 87 124 - error: 125 - return ERR_PTR(afs_end_cursor(&ac)); 88 + ret = afs_end_vlserver_operation(&vc); 89 + return ret < 0 ? ERR_PTR(ret) : vldb; 126 90 } 127 91 128 92 /* ··· 234 270 /* We look up an ID by passing it as a decimal string in the 235 271 * operation's name parameter. 236 272 */ 237 - idsz = sprintf(idbuf, "%u", volume->vid); 273 + idsz = sprintf(idbuf, "%llu", volume->vid); 238 274 239 275 vldb = afs_vl_lookup_vldb(volume->cell, key, idbuf, idsz); 240 276 if (IS_ERR(vldb)) {
+21 -9
fs/afs/write.c
··· 33 33 loff_t pos, unsigned int len, struct page *page) 34 34 { 35 35 struct afs_read *req; 36 + size_t p; 37 + void *data; 36 38 int ret; 37 39 38 40 _enter(",,%llu", (unsigned long long)pos); 41 + 42 + if (pos >= vnode->vfs_inode.i_size) { 43 + p = pos & ~PAGE_MASK; 44 + ASSERTCMP(p + len, <=, PAGE_SIZE); 45 + data = kmap(page); 46 + memset(data + p, 0, len); 47 + kunmap(page); 48 + return 0; 49 + } 39 50 40 51 req = kzalloc(sizeof(struct afs_read) + sizeof(struct page *), 41 52 GFP_KERNEL); ··· 92 81 pgoff_t index = pos >> PAGE_SHIFT; 93 82 int ret; 94 83 95 - _enter("{%x:%u},{%lx},%u,%u", 84 + _enter("{%llx:%llu},{%lx},%u,%u", 96 85 vnode->fid.vid, vnode->fid.vnode, index, from, to); 97 86 98 87 /* We want to store information about how much of a page is altered in ··· 192 181 loff_t i_size, maybe_i_size; 193 182 int ret; 194 183 195 - _enter("{%x:%u},{%lx}", 184 + _enter("{%llx:%llu},{%lx}", 196 185 vnode->fid.vid, vnode->fid.vnode, page->index); 197 186 198 187 maybe_i_size = pos + copied; ··· 241 230 struct pagevec pv; 242 231 unsigned count, loop; 243 232 244 - _enter("{%x:%u},%lx-%lx", 233 + _enter("{%llx:%llu},%lx-%lx", 245 234 vnode->fid.vid, vnode->fid.vnode, first, last); 246 235 247 236 pagevec_init(&pv); ··· 283 272 struct pagevec pv; 284 273 unsigned count, loop; 285 274 286 - _enter("{%x:%u},%lx-%lx", 275 + _enter("{%llx:%llu},%lx-%lx", 287 276 vnode->fid.vid, vnode->fid.vnode, first, last); 288 277 289 278 pagevec_init(&pv); ··· 325 314 struct list_head *p; 326 315 int ret = -ENOKEY, ret2; 327 316 328 - _enter("%s{%x:%u.%u},%lx,%lx,%x,%x", 317 + _enter("%s{%llx:%llu.%u},%lx,%lx,%x,%x", 329 318 vnode->volume->name, 330 319 vnode->fid.vid, 331 320 vnode->fid.vnode, ··· 544 533 case -ENOENT: 545 534 case -ENOMEDIUM: 546 535 case -ENXIO: 536 + trace_afs_file_error(vnode, ret, afs_file_error_writeback_fail); 547 537 afs_kill_pages(mapping, first, last); 548 538 mapping_set_error(mapping, ret); 549 539 break; ··· 687 675 unsigned count, loop; 688 676 pgoff_t first = call->first, last = call->last; 689 677 690 - _enter("{%x:%u},{%lx-%lx}", 678 + _enter("{%llx:%llu},{%lx-%lx}", 691 679 vnode->fid.vid, vnode->fid.vnode, first, last); 692 680 693 681 pagevec_init(&pv); ··· 726 714 ssize_t result; 727 715 size_t count = iov_iter_count(from); 728 716 729 - _enter("{%x.%u},{%zu},", 717 + _enter("{%llx:%llu},{%zu},", 730 718 vnode->fid.vid, vnode->fid.vnode, count); 731 719 732 720 if (IS_SWAPFILE(&vnode->vfs_inode)) { ··· 754 742 struct inode *inode = file_inode(file); 755 743 struct afs_vnode *vnode = AFS_FS_I(inode); 756 744 757 - _enter("{%x:%u},{n=%pD},%d", 745 + _enter("{%llx:%llu},{n=%pD},%d", 758 746 vnode->fid.vid, vnode->fid.vnode, file, 759 747 datasync); 760 748 ··· 772 760 struct afs_vnode *vnode = AFS_FS_I(inode); 773 761 unsigned long priv; 774 762 775 - _enter("{{%x:%u}},{%lx}", 763 + _enter("{{%llx:%llu}},{%lx}", 776 764 vnode->fid.vid, vnode->fid.vnode, vmf->page->index); 777 765 778 766 sb_start_pagefault(inode->i_sb);
+1 -1
fs/afs/xattr.c
··· 72 72 char text[8 + 1 + 8 + 1 + 8 + 1]; 73 73 size_t len; 74 74 75 - len = sprintf(text, "%x:%x:%x", 75 + len = sprintf(text, "%llx:%llx:%x", 76 76 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); 77 77 if (size == 0) 78 78 return len;
+2184
fs/afs/yfsclient.c
··· 1 + /* YFS File Server client stubs 2 + * 3 + * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public Licence 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the Licence, or (at your option) any later version. 10 + */ 11 + 12 + #include <linux/init.h> 13 + #include <linux/slab.h> 14 + #include <linux/sched.h> 15 + #include <linux/circ_buf.h> 16 + #include <linux/iversion.h> 17 + #include "internal.h" 18 + #include "afs_fs.h" 19 + #include "xdr_fs.h" 20 + #include "protocol_yfs.h" 21 + 22 + static const struct afs_fid afs_zero_fid; 23 + 24 + static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi) 25 + { 26 + call->cbi = afs_get_cb_interest(cbi); 27 + } 28 + 29 + #define xdr_size(x) (sizeof(*x) / sizeof(__be32)) 30 + 31 + static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid) 32 + { 33 + const struct yfs_xdr_YFSFid *x = (const void *)*_bp; 34 + 35 + fid->vid = xdr_to_u64(x->volume); 36 + fid->vnode = xdr_to_u64(x->vnode.lo); 37 + fid->vnode_hi = ntohl(x->vnode.hi); 38 + fid->unique = ntohl(x->vnode.unique); 39 + *_bp += xdr_size(x); 40 + } 41 + 42 + static __be32 *xdr_encode_u32(__be32 *bp, u32 n) 43 + { 44 + *bp++ = htonl(n); 45 + return bp; 46 + } 47 + 48 + static __be32 *xdr_encode_u64(__be32 *bp, u64 n) 49 + { 50 + struct yfs_xdr_u64 *x = (void *)bp; 51 + 52 + *x = u64_to_xdr(n); 53 + return bp + xdr_size(x); 54 + } 55 + 56 + static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid) 57 + { 58 + struct yfs_xdr_YFSFid *x = (void *)bp; 59 + 60 + x->volume = u64_to_xdr(fid->vid); 61 + x->vnode.lo = u64_to_xdr(fid->vnode); 62 + x->vnode.hi = htonl(fid->vnode_hi); 63 + x->vnode.unique = htonl(fid->unique); 64 + return bp + xdr_size(x); 65 + } 66 + 67 + static size_t xdr_strlen(unsigned int len) 68 + { 69 + return sizeof(__be32) + round_up(len, sizeof(__be32)); 70 + } 71 + 72 + static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len) 73 + { 74 + bp = xdr_encode_u32(bp, len); 75 + bp = memcpy(bp, p, len); 76 + if (len & 3) { 77 + unsigned int pad = 4 - (len & 3); 78 + 79 + memset((u8 *)bp + len, 0, pad); 80 + len += pad; 81 + } 82 + 83 + return bp + len / sizeof(__be32); 84 + } 85 + 86 + static s64 linux_to_yfs_time(const struct timespec64 *t) 87 + { 88 + /* Convert to 100ns intervals. */ 89 + return (u64)t->tv_sec * 10000000 + t->tv_nsec/100; 90 + } 91 + 92 + static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode) 93 + { 94 + struct yfs_xdr_YFSStoreStatus *x = (void *)bp; 95 + 96 + x->mask = htonl(AFS_SET_MODE); 97 + x->mode = htonl(mode & S_IALLUGO); 98 + x->mtime_client = u64_to_xdr(0); 99 + x->owner = u64_to_xdr(0); 100 + x->group = u64_to_xdr(0); 101 + return bp + xdr_size(x); 102 + } 103 + 104 + static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t) 105 + { 106 + struct yfs_xdr_YFSStoreStatus *x = (void *)bp; 107 + s64 mtime = linux_to_yfs_time(t); 108 + 109 + x->mask = htonl(AFS_SET_MTIME); 110 + x->mode = htonl(0); 111 + x->mtime_client = u64_to_xdr(mtime); 112 + x->owner = u64_to_xdr(0); 113 + x->group = u64_to_xdr(0); 114 + return bp + xdr_size(x); 115 + } 116 + 117 + /* 118 + * Convert a signed 100ns-resolution 64-bit time into a timespec. 119 + */ 120 + static struct timespec64 yfs_time_to_linux(s64 t) 121 + { 122 + struct timespec64 ts; 123 + u64 abs_t; 124 + 125 + /* 126 + * Unfortunately can not use normal 64 bit division on 32 bit arch, but 127 + * the alternative, do_div, does not work with negative numbers so have 128 + * to special case them 129 + */ 130 + if (t < 0) { 131 + abs_t = -t; 132 + ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100); 133 + ts.tv_nsec = -ts.tv_nsec; 134 + ts.tv_sec = -abs_t; 135 + } else { 136 + abs_t = t; 137 + ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100; 138 + ts.tv_sec = abs_t; 139 + } 140 + 141 + return ts; 142 + } 143 + 144 + static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr) 145 + { 146 + s64 t = xdr_to_u64(xdr); 147 + 148 + return yfs_time_to_linux(t); 149 + } 150 + 151 + static void yfs_check_req(struct afs_call *call, __be32 *bp) 152 + { 153 + size_t len = (void *)bp - call->request; 154 + 155 + if (len > call->request_size) 156 + pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n", 157 + call->type->name, len, call->request_size); 158 + else if (len < call->request_size) 159 + pr_warning("kAFS: %s: Request buffer underflow (%zu<%u)\n", 160 + call->type->name, len, call->request_size); 161 + } 162 + 163 + /* 164 + * Dump a bad file status record. 165 + */ 166 + static void xdr_dump_bad(const __be32 *bp) 167 + { 168 + __be32 x[4]; 169 + int i; 170 + 171 + pr_notice("YFS XDR: Bad status record\n"); 172 + for (i = 0; i < 5 * 4 * 4; i += 16) { 173 + memcpy(x, bp, 16); 174 + bp += 4; 175 + pr_notice("%03x: %08x %08x %08x %08x\n", 176 + i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3])); 177 + } 178 + 179 + memcpy(x, bp, 4); 180 + pr_notice("0x50: %08x\n", ntohl(x[0])); 181 + } 182 + 183 + /* 184 + * Decode a YFSFetchStatus block 185 + */ 186 + static int xdr_decode_YFSFetchStatus(struct afs_call *call, 187 + const __be32 **_bp, 188 + struct afs_file_status *status, 189 + struct afs_vnode *vnode, 190 + const afs_dataversion_t *expected_version, 191 + struct afs_read *read_req) 192 + { 193 + const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp; 194 + u32 type; 195 + u8 flags = 0; 196 + 197 + status->abort_code = ntohl(xdr->abort_code); 198 + if (status->abort_code != 0) { 199 + if (vnode && status->abort_code == VNOVNODE) { 200 + set_bit(AFS_VNODE_DELETED, &vnode->flags); 201 + status->nlink = 0; 202 + __afs_break_callback(vnode); 203 + } 204 + return 0; 205 + } 206 + 207 + type = ntohl(xdr->type); 208 + switch (type) { 209 + case AFS_FTYPE_FILE: 210 + case AFS_FTYPE_DIR: 211 + case AFS_FTYPE_SYMLINK: 212 + if (type != status->type && 213 + vnode && 214 + !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 215 + pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n", 216 + vnode->fid.vid, 217 + vnode->fid.vnode, 218 + vnode->fid.unique, 219 + status->type, type); 220 + goto bad; 221 + } 222 + status->type = type; 223 + break; 224 + default: 225 + goto bad; 226 + } 227 + 228 + #define EXTRACT_M4(FIELD) \ 229 + do { \ 230 + u32 x = ntohl(xdr->FIELD); \ 231 + if (status->FIELD != x) { \ 232 + flags |= AFS_VNODE_META_CHANGED; \ 233 + status->FIELD = x; \ 234 + } \ 235 + } while (0) 236 + 237 + #define EXTRACT_M8(FIELD) \ 238 + do { \ 239 + u64 x = xdr_to_u64(xdr->FIELD); \ 240 + if (status->FIELD != x) { \ 241 + flags |= AFS_VNODE_META_CHANGED; \ 242 + status->FIELD = x; \ 243 + } \ 244 + } while (0) 245 + 246 + #define EXTRACT_D8(FIELD) \ 247 + do { \ 248 + u64 x = xdr_to_u64(xdr->FIELD); \ 249 + if (status->FIELD != x) { \ 250 + flags |= AFS_VNODE_DATA_CHANGED; \ 251 + status->FIELD = x; \ 252 + } \ 253 + } while (0) 254 + 255 + EXTRACT_M4(nlink); 256 + EXTRACT_D8(size); 257 + EXTRACT_D8(data_version); 258 + EXTRACT_M8(author); 259 + EXTRACT_M8(owner); 260 + EXTRACT_M8(group); 261 + EXTRACT_M4(mode); 262 + EXTRACT_M4(caller_access); /* call ticket dependent */ 263 + EXTRACT_M4(anon_access); 264 + 265 + status->mtime_client = xdr_to_time(xdr->mtime_client); 266 + status->mtime_server = xdr_to_time(xdr->mtime_server); 267 + status->lock_count = ntohl(xdr->lock_count); 268 + 269 + if (read_req) { 270 + read_req->data_version = status->data_version; 271 + read_req->file_size = status->size; 272 + } 273 + 274 + *_bp += xdr_size(xdr); 275 + 276 + if (vnode) { 277 + if (test_bit(AFS_VNODE_UNSET, &vnode->flags)) 278 + flags |= AFS_VNODE_NOT_YET_SET; 279 + afs_update_inode_from_status(vnode, status, expected_version, 280 + flags); 281 + } 282 + 283 + return 0; 284 + 285 + bad: 286 + xdr_dump_bad(*_bp); 287 + return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); 288 + } 289 + 290 + /* 291 + * Decode the file status. We need to lock the target vnode if we're going to 292 + * update its status so that stat() sees the attributes update atomically. 293 + */ 294 + static int yfs_decode_status(struct afs_call *call, 295 + const __be32 **_bp, 296 + struct afs_file_status *status, 297 + struct afs_vnode *vnode, 298 + const afs_dataversion_t *expected_version, 299 + struct afs_read *read_req) 300 + { 301 + int ret; 302 + 303 + if (!vnode) 304 + return xdr_decode_YFSFetchStatus(call, _bp, status, vnode, 305 + expected_version, read_req); 306 + 307 + write_seqlock(&vnode->cb_lock); 308 + ret = xdr_decode_YFSFetchStatus(call, _bp, status, vnode, 309 + expected_version, read_req); 310 + write_sequnlock(&vnode->cb_lock); 311 + return ret; 312 + } 313 + 314 + /* 315 + * Decode a YFSCallBack block 316 + */ 317 + static void xdr_decode_YFSCallBack(struct afs_call *call, 318 + struct afs_vnode *vnode, 319 + const __be32 **_bp) 320 + { 321 + struct yfs_xdr_YFSCallBack *xdr = (void *)*_bp; 322 + struct afs_cb_interest *old, *cbi = call->cbi; 323 + u64 cb_expiry; 324 + 325 + write_seqlock(&vnode->cb_lock); 326 + 327 + if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) { 328 + cb_expiry = xdr_to_u64(xdr->expiration_time); 329 + do_div(cb_expiry, 10 * 1000 * 1000); 330 + vnode->cb_version = ntohl(xdr->version); 331 + vnode->cb_type = ntohl(xdr->type); 332 + vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds(); 333 + old = vnode->cb_interest; 334 + if (old != call->cbi) { 335 + vnode->cb_interest = cbi; 336 + cbi = old; 337 + } 338 + set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 339 + } 340 + 341 + write_sequnlock(&vnode->cb_lock); 342 + call->cbi = cbi; 343 + *_bp += xdr_size(xdr); 344 + } 345 + 346 + static void xdr_decode_YFSCallBack_raw(const __be32 **_bp, 347 + struct afs_callback *cb) 348 + { 349 + struct yfs_xdr_YFSCallBack *x = (void *)*_bp; 350 + u64 cb_expiry; 351 + 352 + cb_expiry = xdr_to_u64(x->expiration_time); 353 + do_div(cb_expiry, 10 * 1000 * 1000); 354 + cb->version = ntohl(x->version); 355 + cb->type = ntohl(x->type); 356 + cb->expires_at = cb_expiry + ktime_get_real_seconds(); 357 + 358 + *_bp += xdr_size(x); 359 + } 360 + 361 + /* 362 + * Decode a YFSVolSync block 363 + */ 364 + static void xdr_decode_YFSVolSync(const __be32 **_bp, 365 + struct afs_volsync *volsync) 366 + { 367 + struct yfs_xdr_YFSVolSync *x = (void *)*_bp; 368 + u64 creation; 369 + 370 + if (volsync) { 371 + creation = xdr_to_u64(x->vol_creation_date); 372 + do_div(creation, 10 * 1000 * 1000); 373 + volsync->creation = creation; 374 + } 375 + 376 + *_bp += xdr_size(x); 377 + } 378 + 379 + /* 380 + * Encode the requested attributes into a YFSStoreStatus block 381 + */ 382 + static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr) 383 + { 384 + struct yfs_xdr_YFSStoreStatus *x = (void *)bp; 385 + s64 mtime = 0, owner = 0, group = 0; 386 + u32 mask = 0, mode = 0; 387 + 388 + mask = 0; 389 + if (attr->ia_valid & ATTR_MTIME) { 390 + mask |= AFS_SET_MTIME; 391 + mtime = linux_to_yfs_time(&attr->ia_mtime); 392 + } 393 + 394 + if (attr->ia_valid & ATTR_UID) { 395 + mask |= AFS_SET_OWNER; 396 + owner = from_kuid(&init_user_ns, attr->ia_uid); 397 + } 398 + 399 + if (attr->ia_valid & ATTR_GID) { 400 + mask |= AFS_SET_GROUP; 401 + group = from_kgid(&init_user_ns, attr->ia_gid); 402 + } 403 + 404 + if (attr->ia_valid & ATTR_MODE) { 405 + mask |= AFS_SET_MODE; 406 + mode = attr->ia_mode & S_IALLUGO; 407 + } 408 + 409 + x->mask = htonl(mask); 410 + x->mode = htonl(mode); 411 + x->mtime_client = u64_to_xdr(mtime); 412 + x->owner = u64_to_xdr(owner); 413 + x->group = u64_to_xdr(group); 414 + return bp + xdr_size(x); 415 + } 416 + 417 + /* 418 + * Decode a YFSFetchVolumeStatus block. 419 + */ 420 + static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp, 421 + struct afs_volume_status *vs) 422 + { 423 + const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp; 424 + u32 flags; 425 + 426 + vs->vid = xdr_to_u64(x->vid); 427 + vs->parent_id = xdr_to_u64(x->parent_id); 428 + flags = ntohl(x->flags); 429 + vs->online = flags & yfs_FVSOnline; 430 + vs->in_service = flags & yfs_FVSInservice; 431 + vs->blessed = flags & yfs_FVSBlessed; 432 + vs->needs_salvage = flags & yfs_FVSNeedsSalvage; 433 + vs->type = ntohl(x->type); 434 + vs->min_quota = 0; 435 + vs->max_quota = xdr_to_u64(x->max_quota); 436 + vs->blocks_in_use = xdr_to_u64(x->blocks_in_use); 437 + vs->part_blocks_avail = xdr_to_u64(x->part_blocks_avail); 438 + vs->part_max_blocks = xdr_to_u64(x->part_max_blocks); 439 + vs->vol_copy_date = xdr_to_u64(x->vol_copy_date); 440 + vs->vol_backup_date = xdr_to_u64(x->vol_backup_date); 441 + *_bp += sizeof(*x) / sizeof(__be32); 442 + } 443 + 444 + /* 445 + * deliver reply data to an FS.FetchStatus 446 + */ 447 + static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call) 448 + { 449 + struct afs_vnode *vnode = call->reply[0]; 450 + const __be32 *bp; 451 + int ret; 452 + 453 + ret = afs_transfer_reply(call); 454 + if (ret < 0) 455 + return ret; 456 + 457 + _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 458 + 459 + /* unmarshall the reply once we've received all of it */ 460 + bp = call->buffer; 461 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 462 + &call->expected_version, NULL); 463 + if (ret < 0) 464 + return ret; 465 + xdr_decode_YFSCallBack(call, vnode, &bp); 466 + xdr_decode_YFSVolSync(&bp, call->reply[1]); 467 + 468 + _leave(" = 0 [done]"); 469 + return 0; 470 + } 471 + 472 + /* 473 + * YFS.FetchStatus operation type 474 + */ 475 + static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = { 476 + .name = "YFS.FetchStatus(vnode)", 477 + .op = yfs_FS_FetchStatus, 478 + .deliver = yfs_deliver_fs_fetch_status_vnode, 479 + .destructor = afs_flat_call_destructor, 480 + }; 481 + 482 + /* 483 + * Fetch the status information for a file. 484 + */ 485 + int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync, 486 + bool new_inode) 487 + { 488 + struct afs_vnode *vnode = fc->vnode; 489 + struct afs_call *call; 490 + struct afs_net *net = afs_v2net(vnode); 491 + __be32 *bp; 492 + 493 + _enter(",%x,{%llx:%llu},,", 494 + key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 495 + 496 + call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode, 497 + sizeof(__be32) * 2 + 498 + sizeof(struct yfs_xdr_YFSFid), 499 + sizeof(struct yfs_xdr_YFSFetchStatus) + 500 + sizeof(struct yfs_xdr_YFSCallBack) + 501 + sizeof(struct yfs_xdr_YFSVolSync)); 502 + if (!call) { 503 + fc->ac.error = -ENOMEM; 504 + return -ENOMEM; 505 + } 506 + 507 + call->key = fc->key; 508 + call->reply[0] = vnode; 509 + call->reply[1] = volsync; 510 + call->expected_version = new_inode ? 1 : vnode->status.data_version; 511 + 512 + /* marshall the parameters */ 513 + bp = call->request; 514 + bp = xdr_encode_u32(bp, YFSFETCHSTATUS); 515 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 516 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 517 + yfs_check_req(call, bp); 518 + 519 + call->cb_break = fc->cb_break; 520 + afs_use_fs_server(call, fc->cbi); 521 + trace_afs_make_fs_call(call, &vnode->fid); 522 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 523 + } 524 + 525 + /* 526 + * Deliver reply data to an YFS.FetchData64. 527 + */ 528 + static int yfs_deliver_fs_fetch_data64(struct afs_call *call) 529 + { 530 + struct afs_vnode *vnode = call->reply[0]; 531 + struct afs_read *req = call->reply[2]; 532 + const __be32 *bp; 533 + unsigned int size; 534 + int ret; 535 + 536 + _enter("{%u,%zu/%llu}", 537 + call->unmarshall, iov_iter_count(&call->iter), req->actual_len); 538 + 539 + switch (call->unmarshall) { 540 + case 0: 541 + req->actual_len = 0; 542 + req->index = 0; 543 + req->offset = req->pos & (PAGE_SIZE - 1); 544 + afs_extract_to_tmp64(call); 545 + call->unmarshall++; 546 + 547 + /* extract the returned data length */ 548 + case 1: 549 + _debug("extract data length"); 550 + ret = afs_extract_data(call, true); 551 + if (ret < 0) 552 + return ret; 553 + 554 + req->actual_len = be64_to_cpu(call->tmp64); 555 + _debug("DATA length: %llu", req->actual_len); 556 + req->remain = min(req->len, req->actual_len); 557 + if (req->remain == 0) 558 + goto no_more_data; 559 + 560 + call->unmarshall++; 561 + 562 + begin_page: 563 + ASSERTCMP(req->index, <, req->nr_pages); 564 + if (req->remain > PAGE_SIZE - req->offset) 565 + size = PAGE_SIZE - req->offset; 566 + else 567 + size = req->remain; 568 + call->bvec[0].bv_len = size; 569 + call->bvec[0].bv_offset = req->offset; 570 + call->bvec[0].bv_page = req->pages[req->index]; 571 + iov_iter_bvec(&call->iter, READ, call->bvec, 1, size); 572 + ASSERTCMP(size, <=, PAGE_SIZE); 573 + 574 + /* extract the returned data */ 575 + case 2: 576 + _debug("extract data %zu/%llu", 577 + iov_iter_count(&call->iter), req->remain); 578 + 579 + ret = afs_extract_data(call, true); 580 + if (ret < 0) 581 + return ret; 582 + req->remain -= call->bvec[0].bv_len; 583 + req->offset += call->bvec[0].bv_len; 584 + ASSERTCMP(req->offset, <=, PAGE_SIZE); 585 + if (req->offset == PAGE_SIZE) { 586 + req->offset = 0; 587 + if (req->page_done) 588 + req->page_done(call, req); 589 + req->index++; 590 + if (req->remain > 0) 591 + goto begin_page; 592 + } 593 + 594 + ASSERTCMP(req->remain, ==, 0); 595 + if (req->actual_len <= req->len) 596 + goto no_more_data; 597 + 598 + /* Discard any excess data the server gave us */ 599 + iov_iter_discard(&call->iter, READ, req->actual_len - req->len); 600 + call->unmarshall = 3; 601 + case 3: 602 + _debug("extract discard %zu/%llu", 603 + iov_iter_count(&call->iter), req->actual_len - req->len); 604 + 605 + ret = afs_extract_data(call, true); 606 + if (ret < 0) 607 + return ret; 608 + 609 + no_more_data: 610 + call->unmarshall = 4; 611 + afs_extract_to_buf(call, 612 + sizeof(struct yfs_xdr_YFSFetchStatus) + 613 + sizeof(struct yfs_xdr_YFSCallBack) + 614 + sizeof(struct yfs_xdr_YFSVolSync)); 615 + 616 + /* extract the metadata */ 617 + case 4: 618 + ret = afs_extract_data(call, false); 619 + if (ret < 0) 620 + return ret; 621 + 622 + bp = call->buffer; 623 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 624 + &vnode->status.data_version, req); 625 + if (ret < 0) 626 + return ret; 627 + xdr_decode_YFSCallBack(call, vnode, &bp); 628 + xdr_decode_YFSVolSync(&bp, call->reply[1]); 629 + 630 + call->unmarshall++; 631 + 632 + case 5: 633 + break; 634 + } 635 + 636 + for (; req->index < req->nr_pages; req->index++) { 637 + if (req->offset < PAGE_SIZE) 638 + zero_user_segment(req->pages[req->index], 639 + req->offset, PAGE_SIZE); 640 + if (req->page_done) 641 + req->page_done(call, req); 642 + req->offset = 0; 643 + } 644 + 645 + _leave(" = 0 [done]"); 646 + return 0; 647 + } 648 + 649 + static void yfs_fetch_data_destructor(struct afs_call *call) 650 + { 651 + struct afs_read *req = call->reply[2]; 652 + 653 + afs_put_read(req); 654 + afs_flat_call_destructor(call); 655 + } 656 + 657 + /* 658 + * YFS.FetchData64 operation type 659 + */ 660 + static const struct afs_call_type yfs_RXYFSFetchData64 = { 661 + .name = "YFS.FetchData64", 662 + .op = yfs_FS_FetchData64, 663 + .deliver = yfs_deliver_fs_fetch_data64, 664 + .destructor = yfs_fetch_data_destructor, 665 + }; 666 + 667 + /* 668 + * Fetch data from a file. 669 + */ 670 + int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) 671 + { 672 + struct afs_vnode *vnode = fc->vnode; 673 + struct afs_call *call; 674 + struct afs_net *net = afs_v2net(vnode); 675 + __be32 *bp; 676 + 677 + _enter(",%x,{%llx:%llu},%llx,%llx", 678 + key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode, 679 + req->pos, req->len); 680 + 681 + call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64, 682 + sizeof(__be32) * 2 + 683 + sizeof(struct yfs_xdr_YFSFid) + 684 + sizeof(struct yfs_xdr_u64) * 2, 685 + sizeof(struct yfs_xdr_YFSFetchStatus) + 686 + sizeof(struct yfs_xdr_YFSCallBack) + 687 + sizeof(struct yfs_xdr_YFSVolSync)); 688 + if (!call) 689 + return -ENOMEM; 690 + 691 + call->key = fc->key; 692 + call->reply[0] = vnode; 693 + call->reply[1] = NULL; /* volsync */ 694 + call->reply[2] = req; 695 + call->expected_version = vnode->status.data_version; 696 + call->want_reply_time = true; 697 + 698 + /* marshall the parameters */ 699 + bp = call->request; 700 + bp = xdr_encode_u32(bp, YFSFETCHDATA64); 701 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 702 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 703 + bp = xdr_encode_u64(bp, req->pos); 704 + bp = xdr_encode_u64(bp, req->len); 705 + yfs_check_req(call, bp); 706 + 707 + refcount_inc(&req->usage); 708 + call->cb_break = fc->cb_break; 709 + afs_use_fs_server(call, fc->cbi); 710 + trace_afs_make_fs_call(call, &vnode->fid); 711 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 712 + } 713 + 714 + /* 715 + * Deliver reply data for YFS.CreateFile or YFS.MakeDir. 716 + */ 717 + static int yfs_deliver_fs_create_vnode(struct afs_call *call) 718 + { 719 + struct afs_vnode *vnode = call->reply[0]; 720 + const __be32 *bp; 721 + int ret; 722 + 723 + _enter("{%u}", call->unmarshall); 724 + 725 + ret = afs_transfer_reply(call); 726 + if (ret < 0) 727 + return ret; 728 + 729 + /* unmarshall the reply once we've received all of it */ 730 + bp = call->buffer; 731 + xdr_decode_YFSFid(&bp, call->reply[1]); 732 + ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL); 733 + if (ret < 0) 734 + return ret; 735 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 736 + &call->expected_version, NULL); 737 + if (ret < 0) 738 + return ret; 739 + xdr_decode_YFSCallBack_raw(&bp, call->reply[3]); 740 + xdr_decode_YFSVolSync(&bp, NULL); 741 + 742 + _leave(" = 0 [done]"); 743 + return 0; 744 + } 745 + 746 + /* 747 + * FS.CreateFile and FS.MakeDir operation type 748 + */ 749 + static const struct afs_call_type afs_RXFSCreateFile = { 750 + .name = "YFS.CreateFile", 751 + .op = yfs_FS_CreateFile, 752 + .deliver = yfs_deliver_fs_create_vnode, 753 + .destructor = afs_flat_call_destructor, 754 + }; 755 + 756 + /* 757 + * Create a file. 758 + */ 759 + int yfs_fs_create_file(struct afs_fs_cursor *fc, 760 + const char *name, 761 + umode_t mode, 762 + u64 current_data_version, 763 + struct afs_fid *newfid, 764 + struct afs_file_status *newstatus, 765 + struct afs_callback *newcb) 766 + { 767 + struct afs_vnode *vnode = fc->vnode; 768 + struct afs_call *call; 769 + struct afs_net *net = afs_v2net(vnode); 770 + size_t namesz, reqsz, rplsz; 771 + __be32 *bp; 772 + 773 + _enter(""); 774 + 775 + namesz = strlen(name); 776 + reqsz = (sizeof(__be32) + 777 + sizeof(__be32) + 778 + sizeof(struct yfs_xdr_YFSFid) + 779 + xdr_strlen(namesz) + 780 + sizeof(struct yfs_xdr_YFSStoreStatus) + 781 + sizeof(__be32)); 782 + rplsz = (sizeof(struct yfs_xdr_YFSFid) + 783 + sizeof(struct yfs_xdr_YFSFetchStatus) + 784 + sizeof(struct yfs_xdr_YFSFetchStatus) + 785 + sizeof(struct yfs_xdr_YFSCallBack) + 786 + sizeof(struct yfs_xdr_YFSVolSync)); 787 + 788 + call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz); 789 + if (!call) 790 + return -ENOMEM; 791 + 792 + call->key = fc->key; 793 + call->reply[0] = vnode; 794 + call->reply[1] = newfid; 795 + call->reply[2] = newstatus; 796 + call->reply[3] = newcb; 797 + call->expected_version = current_data_version + 1; 798 + 799 + /* marshall the parameters */ 800 + bp = call->request; 801 + bp = xdr_encode_u32(bp, YFSCREATEFILE); 802 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 803 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 804 + bp = xdr_encode_string(bp, name, namesz); 805 + bp = xdr_encode_YFSStoreStatus_mode(bp, mode); 806 + bp = xdr_encode_u32(bp, 0); /* ViceLockType */ 807 + yfs_check_req(call, bp); 808 + 809 + afs_use_fs_server(call, fc->cbi); 810 + trace_afs_make_fs_call(call, &vnode->fid); 811 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 812 + } 813 + 814 + static const struct afs_call_type yfs_RXFSMakeDir = { 815 + .name = "YFS.MakeDir", 816 + .op = yfs_FS_MakeDir, 817 + .deliver = yfs_deliver_fs_create_vnode, 818 + .destructor = afs_flat_call_destructor, 819 + }; 820 + 821 + /* 822 + * Make a directory. 823 + */ 824 + int yfs_fs_make_dir(struct afs_fs_cursor *fc, 825 + const char *name, 826 + umode_t mode, 827 + u64 current_data_version, 828 + struct afs_fid *newfid, 829 + struct afs_file_status *newstatus, 830 + struct afs_callback *newcb) 831 + { 832 + struct afs_vnode *vnode = fc->vnode; 833 + struct afs_call *call; 834 + struct afs_net *net = afs_v2net(vnode); 835 + size_t namesz, reqsz, rplsz; 836 + __be32 *bp; 837 + 838 + _enter(""); 839 + 840 + namesz = strlen(name); 841 + reqsz = (sizeof(__be32) + 842 + sizeof(struct yfs_xdr_RPCFlags) + 843 + sizeof(struct yfs_xdr_YFSFid) + 844 + xdr_strlen(namesz) + 845 + sizeof(struct yfs_xdr_YFSStoreStatus)); 846 + rplsz = (sizeof(struct yfs_xdr_YFSFid) + 847 + sizeof(struct yfs_xdr_YFSFetchStatus) + 848 + sizeof(struct yfs_xdr_YFSFetchStatus) + 849 + sizeof(struct yfs_xdr_YFSCallBack) + 850 + sizeof(struct yfs_xdr_YFSVolSync)); 851 + 852 + call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz); 853 + if (!call) 854 + return -ENOMEM; 855 + 856 + call->key = fc->key; 857 + call->reply[0] = vnode; 858 + call->reply[1] = newfid; 859 + call->reply[2] = newstatus; 860 + call->reply[3] = newcb; 861 + call->expected_version = current_data_version + 1; 862 + 863 + /* marshall the parameters */ 864 + bp = call->request; 865 + bp = xdr_encode_u32(bp, YFSMAKEDIR); 866 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 867 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 868 + bp = xdr_encode_string(bp, name, namesz); 869 + bp = xdr_encode_YFSStoreStatus_mode(bp, mode); 870 + yfs_check_req(call, bp); 871 + 872 + afs_use_fs_server(call, fc->cbi); 873 + trace_afs_make_fs_call(call, &vnode->fid); 874 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 875 + } 876 + 877 + /* 878 + * Deliver reply data to a YFS.RemoveFile2 operation. 879 + */ 880 + static int yfs_deliver_fs_remove_file2(struct afs_call *call) 881 + { 882 + struct afs_vnode *dvnode = call->reply[0]; 883 + struct afs_vnode *vnode = call->reply[1]; 884 + struct afs_fid fid; 885 + const __be32 *bp; 886 + int ret; 887 + 888 + _enter("{%u}", call->unmarshall); 889 + 890 + ret = afs_transfer_reply(call); 891 + if (ret < 0) 892 + return ret; 893 + 894 + /* unmarshall the reply once we've received all of it */ 895 + bp = call->buffer; 896 + ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, 897 + &call->expected_version, NULL); 898 + if (ret < 0) 899 + return ret; 900 + 901 + xdr_decode_YFSFid(&bp, &fid); 902 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL); 903 + if (ret < 0) 904 + return ret; 905 + /* Was deleted if vnode->status.abort_code == VNOVNODE. */ 906 + 907 + xdr_decode_YFSVolSync(&bp, NULL); 908 + return 0; 909 + } 910 + 911 + /* 912 + * YFS.RemoveFile2 operation type. 913 + */ 914 + static const struct afs_call_type yfs_RXYFSRemoveFile2 = { 915 + .name = "YFS.RemoveFile2", 916 + .op = yfs_FS_RemoveFile2, 917 + .deliver = yfs_deliver_fs_remove_file2, 918 + .destructor = afs_flat_call_destructor, 919 + }; 920 + 921 + /* 922 + * Remove a file and retrieve new file status. 923 + */ 924 + int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 925 + const char *name, u64 current_data_version) 926 + { 927 + struct afs_vnode *dvnode = fc->vnode; 928 + struct afs_call *call; 929 + struct afs_net *net = afs_v2net(dvnode); 930 + size_t namesz; 931 + __be32 *bp; 932 + 933 + _enter(""); 934 + 935 + namesz = strlen(name); 936 + 937 + call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2, 938 + sizeof(__be32) + 939 + sizeof(struct yfs_xdr_RPCFlags) + 940 + sizeof(struct yfs_xdr_YFSFid) + 941 + xdr_strlen(namesz), 942 + sizeof(struct yfs_xdr_YFSFetchStatus) + 943 + sizeof(struct yfs_xdr_YFSFid) + 944 + sizeof(struct yfs_xdr_YFSFetchStatus) + 945 + sizeof(struct yfs_xdr_YFSVolSync)); 946 + if (!call) 947 + return -ENOMEM; 948 + 949 + call->key = fc->key; 950 + call->reply[0] = dvnode; 951 + call->reply[1] = vnode; 952 + call->expected_version = current_data_version + 1; 953 + 954 + /* marshall the parameters */ 955 + bp = call->request; 956 + bp = xdr_encode_u32(bp, YFSREMOVEFILE2); 957 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 958 + bp = xdr_encode_YFSFid(bp, &dvnode->fid); 959 + bp = xdr_encode_string(bp, name, namesz); 960 + yfs_check_req(call, bp); 961 + 962 + afs_use_fs_server(call, fc->cbi); 963 + trace_afs_make_fs_call(call, &dvnode->fid); 964 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 965 + } 966 + 967 + /* 968 + * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation. 969 + */ 970 + static int yfs_deliver_fs_remove(struct afs_call *call) 971 + { 972 + struct afs_vnode *dvnode = call->reply[0]; 973 + const __be32 *bp; 974 + int ret; 975 + 976 + _enter("{%u}", call->unmarshall); 977 + 978 + ret = afs_transfer_reply(call); 979 + if (ret < 0) 980 + return ret; 981 + 982 + /* unmarshall the reply once we've received all of it */ 983 + bp = call->buffer; 984 + ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, 985 + &call->expected_version, NULL); 986 + if (ret < 0) 987 + return ret; 988 + 989 + xdr_decode_YFSVolSync(&bp, NULL); 990 + return 0; 991 + } 992 + 993 + /* 994 + * FS.RemoveDir and FS.RemoveFile operation types. 995 + */ 996 + static const struct afs_call_type yfs_RXYFSRemoveFile = { 997 + .name = "YFS.RemoveFile", 998 + .op = yfs_FS_RemoveFile, 999 + .deliver = yfs_deliver_fs_remove, 1000 + .destructor = afs_flat_call_destructor, 1001 + }; 1002 + 1003 + static const struct afs_call_type yfs_RXYFSRemoveDir = { 1004 + .name = "YFS.RemoveDir", 1005 + .op = yfs_FS_RemoveDir, 1006 + .deliver = yfs_deliver_fs_remove, 1007 + .destructor = afs_flat_call_destructor, 1008 + }; 1009 + 1010 + /* 1011 + * remove a file or directory 1012 + */ 1013 + int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 1014 + const char *name, bool isdir, u64 current_data_version) 1015 + { 1016 + struct afs_vnode *dvnode = fc->vnode; 1017 + struct afs_call *call; 1018 + struct afs_net *net = afs_v2net(dvnode); 1019 + size_t namesz; 1020 + __be32 *bp; 1021 + 1022 + _enter(""); 1023 + 1024 + namesz = strlen(name); 1025 + call = afs_alloc_flat_call( 1026 + net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile, 1027 + sizeof(__be32) + 1028 + sizeof(struct yfs_xdr_RPCFlags) + 1029 + sizeof(struct yfs_xdr_YFSFid) + 1030 + xdr_strlen(namesz), 1031 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1032 + sizeof(struct yfs_xdr_YFSVolSync)); 1033 + if (!call) 1034 + return -ENOMEM; 1035 + 1036 + call->key = fc->key; 1037 + call->reply[0] = dvnode; 1038 + call->reply[1] = vnode; 1039 + call->expected_version = current_data_version + 1; 1040 + 1041 + /* marshall the parameters */ 1042 + bp = call->request; 1043 + bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE); 1044 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1045 + bp = xdr_encode_YFSFid(bp, &dvnode->fid); 1046 + bp = xdr_encode_string(bp, name, namesz); 1047 + yfs_check_req(call, bp); 1048 + 1049 + afs_use_fs_server(call, fc->cbi); 1050 + trace_afs_make_fs_call(call, &dvnode->fid); 1051 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1052 + } 1053 + 1054 + /* 1055 + * Deliver reply data to a YFS.Link operation. 1056 + */ 1057 + static int yfs_deliver_fs_link(struct afs_call *call) 1058 + { 1059 + struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1]; 1060 + const __be32 *bp; 1061 + int ret; 1062 + 1063 + _enter("{%u}", call->unmarshall); 1064 + 1065 + ret = afs_transfer_reply(call); 1066 + if (ret < 0) 1067 + return ret; 1068 + 1069 + /* unmarshall the reply once we've received all of it */ 1070 + bp = call->buffer; 1071 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL); 1072 + if (ret < 0) 1073 + return ret; 1074 + ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode, 1075 + &call->expected_version, NULL); 1076 + if (ret < 0) 1077 + return ret; 1078 + xdr_decode_YFSVolSync(&bp, NULL); 1079 + _leave(" = 0 [done]"); 1080 + return 0; 1081 + } 1082 + 1083 + /* 1084 + * YFS.Link operation type. 1085 + */ 1086 + static const struct afs_call_type yfs_RXYFSLink = { 1087 + .name = "YFS.Link", 1088 + .op = yfs_FS_Link, 1089 + .deliver = yfs_deliver_fs_link, 1090 + .destructor = afs_flat_call_destructor, 1091 + }; 1092 + 1093 + /* 1094 + * Make a hard link. 1095 + */ 1096 + int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 1097 + const char *name, u64 current_data_version) 1098 + { 1099 + struct afs_vnode *dvnode = fc->vnode; 1100 + struct afs_call *call; 1101 + struct afs_net *net = afs_v2net(vnode); 1102 + size_t namesz; 1103 + __be32 *bp; 1104 + 1105 + _enter(""); 1106 + 1107 + namesz = strlen(name); 1108 + call = afs_alloc_flat_call(net, &yfs_RXYFSLink, 1109 + sizeof(__be32) + 1110 + sizeof(struct yfs_xdr_RPCFlags) + 1111 + sizeof(struct yfs_xdr_YFSFid) + 1112 + xdr_strlen(namesz) + 1113 + sizeof(struct yfs_xdr_YFSFid), 1114 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1115 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1116 + sizeof(struct yfs_xdr_YFSVolSync)); 1117 + if (!call) 1118 + return -ENOMEM; 1119 + 1120 + call->key = fc->key; 1121 + call->reply[0] = dvnode; 1122 + call->reply[1] = vnode; 1123 + call->expected_version = current_data_version + 1; 1124 + 1125 + /* marshall the parameters */ 1126 + bp = call->request; 1127 + bp = xdr_encode_u32(bp, YFSLINK); 1128 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1129 + bp = xdr_encode_YFSFid(bp, &dvnode->fid); 1130 + bp = xdr_encode_string(bp, name, namesz); 1131 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1132 + yfs_check_req(call, bp); 1133 + 1134 + afs_use_fs_server(call, fc->cbi); 1135 + trace_afs_make_fs_call(call, &vnode->fid); 1136 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1137 + } 1138 + 1139 + /* 1140 + * Deliver reply data to a YFS.Symlink operation. 1141 + */ 1142 + static int yfs_deliver_fs_symlink(struct afs_call *call) 1143 + { 1144 + struct afs_vnode *vnode = call->reply[0]; 1145 + const __be32 *bp; 1146 + int ret; 1147 + 1148 + _enter("{%u}", call->unmarshall); 1149 + 1150 + ret = afs_transfer_reply(call); 1151 + if (ret < 0) 1152 + return ret; 1153 + 1154 + /* unmarshall the reply once we've received all of it */ 1155 + bp = call->buffer; 1156 + xdr_decode_YFSFid(&bp, call->reply[1]); 1157 + ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL); 1158 + if (ret < 0) 1159 + return ret; 1160 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 1161 + &call->expected_version, NULL); 1162 + if (ret < 0) 1163 + return ret; 1164 + xdr_decode_YFSVolSync(&bp, NULL); 1165 + 1166 + _leave(" = 0 [done]"); 1167 + return 0; 1168 + } 1169 + 1170 + /* 1171 + * YFS.Symlink operation type 1172 + */ 1173 + static const struct afs_call_type yfs_RXYFSSymlink = { 1174 + .name = "YFS.Symlink", 1175 + .op = yfs_FS_Symlink, 1176 + .deliver = yfs_deliver_fs_symlink, 1177 + .destructor = afs_flat_call_destructor, 1178 + }; 1179 + 1180 + /* 1181 + * Create a symbolic link. 1182 + */ 1183 + int yfs_fs_symlink(struct afs_fs_cursor *fc, 1184 + const char *name, 1185 + const char *contents, 1186 + u64 current_data_version, 1187 + struct afs_fid *newfid, 1188 + struct afs_file_status *newstatus) 1189 + { 1190 + struct afs_vnode *dvnode = fc->vnode; 1191 + struct afs_call *call; 1192 + struct afs_net *net = afs_v2net(dvnode); 1193 + size_t namesz, contents_sz; 1194 + __be32 *bp; 1195 + 1196 + _enter(""); 1197 + 1198 + namesz = strlen(name); 1199 + contents_sz = strlen(contents); 1200 + call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink, 1201 + sizeof(__be32) + 1202 + sizeof(struct yfs_xdr_RPCFlags) + 1203 + sizeof(struct yfs_xdr_YFSFid) + 1204 + xdr_strlen(namesz) + 1205 + xdr_strlen(contents_sz) + 1206 + sizeof(struct yfs_xdr_YFSStoreStatus), 1207 + sizeof(struct yfs_xdr_YFSFid) + 1208 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1209 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1210 + sizeof(struct yfs_xdr_YFSVolSync)); 1211 + if (!call) 1212 + return -ENOMEM; 1213 + 1214 + call->key = fc->key; 1215 + call->reply[0] = dvnode; 1216 + call->reply[1] = newfid; 1217 + call->reply[2] = newstatus; 1218 + call->expected_version = current_data_version + 1; 1219 + 1220 + /* marshall the parameters */ 1221 + bp = call->request; 1222 + bp = xdr_encode_u32(bp, YFSSYMLINK); 1223 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1224 + bp = xdr_encode_YFSFid(bp, &dvnode->fid); 1225 + bp = xdr_encode_string(bp, name, namesz); 1226 + bp = xdr_encode_string(bp, contents, contents_sz); 1227 + bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO); 1228 + yfs_check_req(call, bp); 1229 + 1230 + afs_use_fs_server(call, fc->cbi); 1231 + trace_afs_make_fs_call(call, &dvnode->fid); 1232 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1233 + } 1234 + 1235 + /* 1236 + * Deliver reply data to a YFS.Rename operation. 1237 + */ 1238 + static int yfs_deliver_fs_rename(struct afs_call *call) 1239 + { 1240 + struct afs_vnode *orig_dvnode = call->reply[0]; 1241 + struct afs_vnode *new_dvnode = call->reply[1]; 1242 + const __be32 *bp; 1243 + int ret; 1244 + 1245 + _enter("{%u}", call->unmarshall); 1246 + 1247 + ret = afs_transfer_reply(call); 1248 + if (ret < 0) 1249 + return ret; 1250 + 1251 + /* unmarshall the reply once we've received all of it */ 1252 + bp = call->buffer; 1253 + ret = yfs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode, 1254 + &call->expected_version, NULL); 1255 + if (ret < 0) 1256 + return ret; 1257 + if (new_dvnode != orig_dvnode) { 1258 + ret = yfs_decode_status(call, &bp, &new_dvnode->status, new_dvnode, 1259 + &call->expected_version_2, NULL); 1260 + if (ret < 0) 1261 + return ret; 1262 + } 1263 + 1264 + xdr_decode_YFSVolSync(&bp, NULL); 1265 + _leave(" = 0 [done]"); 1266 + return 0; 1267 + } 1268 + 1269 + /* 1270 + * YFS.Rename operation type 1271 + */ 1272 + static const struct afs_call_type yfs_RXYFSRename = { 1273 + .name = "FS.Rename", 1274 + .op = yfs_FS_Rename, 1275 + .deliver = yfs_deliver_fs_rename, 1276 + .destructor = afs_flat_call_destructor, 1277 + }; 1278 + 1279 + /* 1280 + * Rename a file or directory. 1281 + */ 1282 + int yfs_fs_rename(struct afs_fs_cursor *fc, 1283 + const char *orig_name, 1284 + struct afs_vnode *new_dvnode, 1285 + const char *new_name, 1286 + u64 current_orig_data_version, 1287 + u64 current_new_data_version) 1288 + { 1289 + struct afs_vnode *orig_dvnode = fc->vnode; 1290 + struct afs_call *call; 1291 + struct afs_net *net = afs_v2net(orig_dvnode); 1292 + size_t o_namesz, n_namesz; 1293 + __be32 *bp; 1294 + 1295 + _enter(""); 1296 + 1297 + o_namesz = strlen(orig_name); 1298 + n_namesz = strlen(new_name); 1299 + call = afs_alloc_flat_call(net, &yfs_RXYFSRename, 1300 + sizeof(__be32) + 1301 + sizeof(struct yfs_xdr_RPCFlags) + 1302 + sizeof(struct yfs_xdr_YFSFid) + 1303 + xdr_strlen(o_namesz) + 1304 + sizeof(struct yfs_xdr_YFSFid) + 1305 + xdr_strlen(n_namesz), 1306 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1307 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1308 + sizeof(struct yfs_xdr_YFSVolSync)); 1309 + if (!call) 1310 + return -ENOMEM; 1311 + 1312 + call->key = fc->key; 1313 + call->reply[0] = orig_dvnode; 1314 + call->reply[1] = new_dvnode; 1315 + call->expected_version = current_orig_data_version + 1; 1316 + call->expected_version_2 = current_new_data_version + 1; 1317 + 1318 + /* marshall the parameters */ 1319 + bp = call->request; 1320 + bp = xdr_encode_u32(bp, YFSRENAME); 1321 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1322 + bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid); 1323 + bp = xdr_encode_string(bp, orig_name, o_namesz); 1324 + bp = xdr_encode_YFSFid(bp, &new_dvnode->fid); 1325 + bp = xdr_encode_string(bp, new_name, n_namesz); 1326 + yfs_check_req(call, bp); 1327 + 1328 + afs_use_fs_server(call, fc->cbi); 1329 + trace_afs_make_fs_call(call, &orig_dvnode->fid); 1330 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1331 + } 1332 + 1333 + /* 1334 + * Deliver reply data to a YFS.StoreData64 operation. 1335 + */ 1336 + static int yfs_deliver_fs_store_data(struct afs_call *call) 1337 + { 1338 + struct afs_vnode *vnode = call->reply[0]; 1339 + const __be32 *bp; 1340 + int ret; 1341 + 1342 + _enter(""); 1343 + 1344 + ret = afs_transfer_reply(call); 1345 + if (ret < 0) 1346 + return ret; 1347 + 1348 + /* unmarshall the reply once we've received all of it */ 1349 + bp = call->buffer; 1350 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 1351 + &call->expected_version, NULL); 1352 + if (ret < 0) 1353 + return ret; 1354 + xdr_decode_YFSVolSync(&bp, NULL); 1355 + 1356 + afs_pages_written_back(vnode, call); 1357 + 1358 + _leave(" = 0 [done]"); 1359 + return 0; 1360 + } 1361 + 1362 + /* 1363 + * YFS.StoreData64 operation type. 1364 + */ 1365 + static const struct afs_call_type yfs_RXYFSStoreData64 = { 1366 + .name = "YFS.StoreData64", 1367 + .op = yfs_FS_StoreData64, 1368 + .deliver = yfs_deliver_fs_store_data, 1369 + .destructor = afs_flat_call_destructor, 1370 + }; 1371 + 1372 + /* 1373 + * Store a set of pages to a large file. 1374 + */ 1375 + int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, 1376 + pgoff_t first, pgoff_t last, 1377 + unsigned offset, unsigned to) 1378 + { 1379 + struct afs_vnode *vnode = fc->vnode; 1380 + struct afs_call *call; 1381 + struct afs_net *net = afs_v2net(vnode); 1382 + loff_t size, pos, i_size; 1383 + __be32 *bp; 1384 + 1385 + _enter(",%x,{%llx:%llu},,", 1386 + key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1387 + 1388 + size = (loff_t)to - (loff_t)offset; 1389 + if (first != last) 1390 + size += (loff_t)(last - first) << PAGE_SHIFT; 1391 + pos = (loff_t)first << PAGE_SHIFT; 1392 + pos += offset; 1393 + 1394 + i_size = i_size_read(&vnode->vfs_inode); 1395 + if (pos + size > i_size) 1396 + i_size = size + pos; 1397 + 1398 + _debug("size %llx, at %llx, i_size %llx", 1399 + (unsigned long long)size, (unsigned long long)pos, 1400 + (unsigned long long)i_size); 1401 + 1402 + call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64, 1403 + sizeof(__be32) + 1404 + sizeof(__be32) + 1405 + sizeof(struct yfs_xdr_YFSFid) + 1406 + sizeof(struct yfs_xdr_YFSStoreStatus) + 1407 + sizeof(struct yfs_xdr_u64) * 3, 1408 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1409 + sizeof(struct yfs_xdr_YFSVolSync)); 1410 + if (!call) 1411 + return -ENOMEM; 1412 + 1413 + call->key = fc->key; 1414 + call->mapping = mapping; 1415 + call->reply[0] = vnode; 1416 + call->first = first; 1417 + call->last = last; 1418 + call->first_offset = offset; 1419 + call->last_to = to; 1420 + call->send_pages = true; 1421 + call->expected_version = vnode->status.data_version + 1; 1422 + 1423 + /* marshall the parameters */ 1424 + bp = call->request; 1425 + bp = xdr_encode_u32(bp, YFSSTOREDATA64); 1426 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1427 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1428 + bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime); 1429 + bp = xdr_encode_u64(bp, pos); 1430 + bp = xdr_encode_u64(bp, size); 1431 + bp = xdr_encode_u64(bp, i_size); 1432 + yfs_check_req(call, bp); 1433 + 1434 + afs_use_fs_server(call, fc->cbi); 1435 + trace_afs_make_fs_call(call, &vnode->fid); 1436 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1437 + } 1438 + 1439 + /* 1440 + * deliver reply data to an FS.StoreStatus 1441 + */ 1442 + static int yfs_deliver_fs_store_status(struct afs_call *call) 1443 + { 1444 + struct afs_vnode *vnode = call->reply[0]; 1445 + const __be32 *bp; 1446 + int ret; 1447 + 1448 + _enter(""); 1449 + 1450 + ret = afs_transfer_reply(call); 1451 + if (ret < 0) 1452 + return ret; 1453 + 1454 + /* unmarshall the reply once we've received all of it */ 1455 + bp = call->buffer; 1456 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 1457 + &call->expected_version, NULL); 1458 + if (ret < 0) 1459 + return ret; 1460 + xdr_decode_YFSVolSync(&bp, NULL); 1461 + 1462 + _leave(" = 0 [done]"); 1463 + return 0; 1464 + } 1465 + 1466 + /* 1467 + * YFS.StoreStatus operation type 1468 + */ 1469 + static const struct afs_call_type yfs_RXYFSStoreStatus = { 1470 + .name = "YFS.StoreStatus", 1471 + .op = yfs_FS_StoreStatus, 1472 + .deliver = yfs_deliver_fs_store_status, 1473 + .destructor = afs_flat_call_destructor, 1474 + }; 1475 + 1476 + static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = { 1477 + .name = "YFS.StoreData64", 1478 + .op = yfs_FS_StoreData64, 1479 + .deliver = yfs_deliver_fs_store_status, 1480 + .destructor = afs_flat_call_destructor, 1481 + }; 1482 + 1483 + /* 1484 + * Set the attributes on a file, using YFS.StoreData64 rather than 1485 + * YFS.StoreStatus so as to alter the file size also. 1486 + */ 1487 + static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr) 1488 + { 1489 + struct afs_vnode *vnode = fc->vnode; 1490 + struct afs_call *call; 1491 + struct afs_net *net = afs_v2net(vnode); 1492 + __be32 *bp; 1493 + 1494 + _enter(",%x,{%llx:%llu},,", 1495 + key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1496 + 1497 + call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status, 1498 + sizeof(__be32) * 2 + 1499 + sizeof(struct yfs_xdr_YFSFid) + 1500 + sizeof(struct yfs_xdr_YFSStoreStatus) + 1501 + sizeof(struct yfs_xdr_u64) * 3, 1502 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1503 + sizeof(struct yfs_xdr_YFSVolSync)); 1504 + if (!call) 1505 + return -ENOMEM; 1506 + 1507 + call->key = fc->key; 1508 + call->reply[0] = vnode; 1509 + call->expected_version = vnode->status.data_version + 1; 1510 + 1511 + /* marshall the parameters */ 1512 + bp = call->request; 1513 + bp = xdr_encode_u32(bp, YFSSTOREDATA64); 1514 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1515 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1516 + bp = xdr_encode_YFS_StoreStatus(bp, attr); 1517 + bp = xdr_encode_u64(bp, 0); /* position of start of write */ 1518 + bp = xdr_encode_u64(bp, 0); /* size of write */ 1519 + bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */ 1520 + yfs_check_req(call, bp); 1521 + 1522 + afs_use_fs_server(call, fc->cbi); 1523 + trace_afs_make_fs_call(call, &vnode->fid); 1524 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1525 + } 1526 + 1527 + /* 1528 + * Set the attributes on a file, using YFS.StoreData64 if there's a change in 1529 + * file size, and YFS.StoreStatus otherwise. 1530 + */ 1531 + int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr) 1532 + { 1533 + struct afs_vnode *vnode = fc->vnode; 1534 + struct afs_call *call; 1535 + struct afs_net *net = afs_v2net(vnode); 1536 + __be32 *bp; 1537 + 1538 + if (attr->ia_valid & ATTR_SIZE) 1539 + return yfs_fs_setattr_size(fc, attr); 1540 + 1541 + _enter(",%x,{%llx:%llu},,", 1542 + key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1543 + 1544 + call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus, 1545 + sizeof(__be32) * 2 + 1546 + sizeof(struct yfs_xdr_YFSFid) + 1547 + sizeof(struct yfs_xdr_YFSStoreStatus), 1548 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1549 + sizeof(struct yfs_xdr_YFSVolSync)); 1550 + if (!call) 1551 + return -ENOMEM; 1552 + 1553 + call->key = fc->key; 1554 + call->reply[0] = vnode; 1555 + call->expected_version = vnode->status.data_version; 1556 + 1557 + /* marshall the parameters */ 1558 + bp = call->request; 1559 + bp = xdr_encode_u32(bp, YFSSTORESTATUS); 1560 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1561 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1562 + bp = xdr_encode_YFS_StoreStatus(bp, attr); 1563 + yfs_check_req(call, bp); 1564 + 1565 + afs_use_fs_server(call, fc->cbi); 1566 + trace_afs_make_fs_call(call, &vnode->fid); 1567 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1568 + } 1569 + 1570 + /* 1571 + * Deliver reply data to a YFS.GetVolumeStatus operation. 1572 + */ 1573 + static int yfs_deliver_fs_get_volume_status(struct afs_call *call) 1574 + { 1575 + const __be32 *bp; 1576 + char *p; 1577 + u32 size; 1578 + int ret; 1579 + 1580 + _enter("{%u}", call->unmarshall); 1581 + 1582 + switch (call->unmarshall) { 1583 + case 0: 1584 + call->unmarshall++; 1585 + afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus)); 1586 + 1587 + /* extract the returned status record */ 1588 + case 1: 1589 + _debug("extract status"); 1590 + ret = afs_extract_data(call, true); 1591 + if (ret < 0) 1592 + return ret; 1593 + 1594 + bp = call->buffer; 1595 + xdr_decode_YFSFetchVolumeStatus(&bp, call->reply[1]); 1596 + call->unmarshall++; 1597 + afs_extract_to_tmp(call); 1598 + 1599 + /* extract the volume name length */ 1600 + case 2: 1601 + ret = afs_extract_data(call, true); 1602 + if (ret < 0) 1603 + return ret; 1604 + 1605 + call->count = ntohl(call->tmp); 1606 + _debug("volname length: %u", call->count); 1607 + if (call->count >= AFSNAMEMAX) 1608 + return afs_protocol_error(call, -EBADMSG, 1609 + afs_eproto_volname_len); 1610 + size = (call->count + 3) & ~3; /* It's padded */ 1611 + afs_extract_begin(call, call->reply[2], size); 1612 + call->unmarshall++; 1613 + 1614 + /* extract the volume name */ 1615 + case 3: 1616 + _debug("extract volname"); 1617 + ret = afs_extract_data(call, true); 1618 + if (ret < 0) 1619 + return ret; 1620 + 1621 + p = call->reply[2]; 1622 + p[call->count] = 0; 1623 + _debug("volname '%s'", p); 1624 + afs_extract_to_tmp(call); 1625 + call->unmarshall++; 1626 + 1627 + /* extract the offline message length */ 1628 + case 4: 1629 + ret = afs_extract_data(call, true); 1630 + if (ret < 0) 1631 + return ret; 1632 + 1633 + call->count = ntohl(call->tmp); 1634 + _debug("offline msg length: %u", call->count); 1635 + if (call->count >= AFSNAMEMAX) 1636 + return afs_protocol_error(call, -EBADMSG, 1637 + afs_eproto_offline_msg_len); 1638 + size = (call->count + 3) & ~3; /* It's padded */ 1639 + afs_extract_begin(call, call->reply[2], size); 1640 + call->unmarshall++; 1641 + 1642 + /* extract the offline message */ 1643 + case 5: 1644 + _debug("extract offline"); 1645 + ret = afs_extract_data(call, true); 1646 + if (ret < 0) 1647 + return ret; 1648 + 1649 + p = call->reply[2]; 1650 + p[call->count] = 0; 1651 + _debug("offline '%s'", p); 1652 + 1653 + afs_extract_to_tmp(call); 1654 + call->unmarshall++; 1655 + 1656 + /* extract the message of the day length */ 1657 + case 6: 1658 + ret = afs_extract_data(call, true); 1659 + if (ret < 0) 1660 + return ret; 1661 + 1662 + call->count = ntohl(call->tmp); 1663 + _debug("motd length: %u", call->count); 1664 + if (call->count >= AFSNAMEMAX) 1665 + return afs_protocol_error(call, -EBADMSG, 1666 + afs_eproto_motd_len); 1667 + size = (call->count + 3) & ~3; /* It's padded */ 1668 + afs_extract_begin(call, call->reply[2], size); 1669 + call->unmarshall++; 1670 + 1671 + /* extract the message of the day */ 1672 + case 7: 1673 + _debug("extract motd"); 1674 + ret = afs_extract_data(call, false); 1675 + if (ret < 0) 1676 + return ret; 1677 + 1678 + p = call->reply[2]; 1679 + p[call->count] = 0; 1680 + _debug("motd '%s'", p); 1681 + 1682 + call->unmarshall++; 1683 + 1684 + case 8: 1685 + break; 1686 + } 1687 + 1688 + _leave(" = 0 [done]"); 1689 + return 0; 1690 + } 1691 + 1692 + /* 1693 + * Destroy a YFS.GetVolumeStatus call. 1694 + */ 1695 + static void yfs_get_volume_status_call_destructor(struct afs_call *call) 1696 + { 1697 + kfree(call->reply[2]); 1698 + call->reply[2] = NULL; 1699 + afs_flat_call_destructor(call); 1700 + } 1701 + 1702 + /* 1703 + * YFS.GetVolumeStatus operation type 1704 + */ 1705 + static const struct afs_call_type yfs_RXYFSGetVolumeStatus = { 1706 + .name = "YFS.GetVolumeStatus", 1707 + .op = yfs_FS_GetVolumeStatus, 1708 + .deliver = yfs_deliver_fs_get_volume_status, 1709 + .destructor = yfs_get_volume_status_call_destructor, 1710 + }; 1711 + 1712 + /* 1713 + * fetch the status of a volume 1714 + */ 1715 + int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, 1716 + struct afs_volume_status *vs) 1717 + { 1718 + struct afs_vnode *vnode = fc->vnode; 1719 + struct afs_call *call; 1720 + struct afs_net *net = afs_v2net(vnode); 1721 + __be32 *bp; 1722 + void *tmpbuf; 1723 + 1724 + _enter(""); 1725 + 1726 + tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL); 1727 + if (!tmpbuf) 1728 + return -ENOMEM; 1729 + 1730 + call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus, 1731 + sizeof(__be32) * 2 + 1732 + sizeof(struct yfs_xdr_u64), 1733 + sizeof(struct yfs_xdr_YFSFetchVolumeStatus) + 1734 + sizeof(__be32)); 1735 + if (!call) { 1736 + kfree(tmpbuf); 1737 + return -ENOMEM; 1738 + } 1739 + 1740 + call->key = fc->key; 1741 + call->reply[0] = vnode; 1742 + call->reply[1] = vs; 1743 + call->reply[2] = tmpbuf; 1744 + 1745 + /* marshall the parameters */ 1746 + bp = call->request; 1747 + bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS); 1748 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1749 + bp = xdr_encode_u64(bp, vnode->fid.vid); 1750 + yfs_check_req(call, bp); 1751 + 1752 + afs_use_fs_server(call, fc->cbi); 1753 + trace_afs_make_fs_call(call, &vnode->fid); 1754 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1755 + } 1756 + 1757 + /* 1758 + * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock 1759 + */ 1760 + static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) 1761 + { 1762 + struct afs_vnode *vnode = call->reply[0]; 1763 + const __be32 *bp; 1764 + int ret; 1765 + 1766 + _enter("{%u}", call->unmarshall); 1767 + 1768 + ret = afs_transfer_reply(call); 1769 + if (ret < 0) 1770 + return ret; 1771 + 1772 + /* unmarshall the reply once we've received all of it */ 1773 + bp = call->buffer; 1774 + ret = yfs_decode_status(call, &bp, &vnode->status, vnode, 1775 + &call->expected_version, NULL); 1776 + if (ret < 0) 1777 + return ret; 1778 + xdr_decode_YFSVolSync(&bp, NULL); 1779 + 1780 + _leave(" = 0 [done]"); 1781 + return 0; 1782 + } 1783 + 1784 + /* 1785 + * YFS.SetLock operation type 1786 + */ 1787 + static const struct afs_call_type yfs_RXYFSSetLock = { 1788 + .name = "YFS.SetLock", 1789 + .op = yfs_FS_SetLock, 1790 + .deliver = yfs_deliver_fs_xxxx_lock, 1791 + .destructor = afs_flat_call_destructor, 1792 + }; 1793 + 1794 + /* 1795 + * YFS.ExtendLock operation type 1796 + */ 1797 + static const struct afs_call_type yfs_RXYFSExtendLock = { 1798 + .name = "YFS.ExtendLock", 1799 + .op = yfs_FS_ExtendLock, 1800 + .deliver = yfs_deliver_fs_xxxx_lock, 1801 + .destructor = afs_flat_call_destructor, 1802 + }; 1803 + 1804 + /* 1805 + * YFS.ReleaseLock operation type 1806 + */ 1807 + static const struct afs_call_type yfs_RXYFSReleaseLock = { 1808 + .name = "YFS.ReleaseLock", 1809 + .op = yfs_FS_ReleaseLock, 1810 + .deliver = yfs_deliver_fs_xxxx_lock, 1811 + .destructor = afs_flat_call_destructor, 1812 + }; 1813 + 1814 + /* 1815 + * Set a lock on a file 1816 + */ 1817 + int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) 1818 + { 1819 + struct afs_vnode *vnode = fc->vnode; 1820 + struct afs_call *call; 1821 + struct afs_net *net = afs_v2net(vnode); 1822 + __be32 *bp; 1823 + 1824 + _enter(""); 1825 + 1826 + call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock, 1827 + sizeof(__be32) * 2 + 1828 + sizeof(struct yfs_xdr_YFSFid) + 1829 + sizeof(__be32), 1830 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1831 + sizeof(struct yfs_xdr_YFSVolSync)); 1832 + if (!call) 1833 + return -ENOMEM; 1834 + 1835 + call->key = fc->key; 1836 + call->reply[0] = vnode; 1837 + 1838 + /* marshall the parameters */ 1839 + bp = call->request; 1840 + bp = xdr_encode_u32(bp, YFSSETLOCK); 1841 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1842 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1843 + bp = xdr_encode_u32(bp, type); 1844 + yfs_check_req(call, bp); 1845 + 1846 + afs_use_fs_server(call, fc->cbi); 1847 + trace_afs_make_fs_call(call, &vnode->fid); 1848 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1849 + } 1850 + 1851 + /* 1852 + * extend a lock on a file 1853 + */ 1854 + int yfs_fs_extend_lock(struct afs_fs_cursor *fc) 1855 + { 1856 + struct afs_vnode *vnode = fc->vnode; 1857 + struct afs_call *call; 1858 + struct afs_net *net = afs_v2net(vnode); 1859 + __be32 *bp; 1860 + 1861 + _enter(""); 1862 + 1863 + call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock, 1864 + sizeof(__be32) * 2 + 1865 + sizeof(struct yfs_xdr_YFSFid), 1866 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1867 + sizeof(struct yfs_xdr_YFSVolSync)); 1868 + if (!call) 1869 + return -ENOMEM; 1870 + 1871 + call->key = fc->key; 1872 + call->reply[0] = vnode; 1873 + 1874 + /* marshall the parameters */ 1875 + bp = call->request; 1876 + bp = xdr_encode_u32(bp, YFSEXTENDLOCK); 1877 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1878 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1879 + yfs_check_req(call, bp); 1880 + 1881 + afs_use_fs_server(call, fc->cbi); 1882 + trace_afs_make_fs_call(call, &vnode->fid); 1883 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1884 + } 1885 + 1886 + /* 1887 + * release a lock on a file 1888 + */ 1889 + int yfs_fs_release_lock(struct afs_fs_cursor *fc) 1890 + { 1891 + struct afs_vnode *vnode = fc->vnode; 1892 + struct afs_call *call; 1893 + struct afs_net *net = afs_v2net(vnode); 1894 + __be32 *bp; 1895 + 1896 + _enter(""); 1897 + 1898 + call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock, 1899 + sizeof(__be32) * 2 + 1900 + sizeof(struct yfs_xdr_YFSFid), 1901 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1902 + sizeof(struct yfs_xdr_YFSVolSync)); 1903 + if (!call) 1904 + return -ENOMEM; 1905 + 1906 + call->key = fc->key; 1907 + call->reply[0] = vnode; 1908 + 1909 + /* marshall the parameters */ 1910 + bp = call->request; 1911 + bp = xdr_encode_u32(bp, YFSRELEASELOCK); 1912 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 1913 + bp = xdr_encode_YFSFid(bp, &vnode->fid); 1914 + yfs_check_req(call, bp); 1915 + 1916 + afs_use_fs_server(call, fc->cbi); 1917 + trace_afs_make_fs_call(call, &vnode->fid); 1918 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 1919 + } 1920 + 1921 + /* 1922 + * Deliver reply data to an FS.FetchStatus with no vnode. 1923 + */ 1924 + static int yfs_deliver_fs_fetch_status(struct afs_call *call) 1925 + { 1926 + struct afs_file_status *status = call->reply[1]; 1927 + struct afs_callback *callback = call->reply[2]; 1928 + struct afs_volsync *volsync = call->reply[3]; 1929 + struct afs_vnode *vnode = call->reply[0]; 1930 + const __be32 *bp; 1931 + int ret; 1932 + 1933 + ret = afs_transfer_reply(call); 1934 + if (ret < 0) 1935 + return ret; 1936 + 1937 + _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 1938 + 1939 + /* unmarshall the reply once we've received all of it */ 1940 + bp = call->buffer; 1941 + ret = yfs_decode_status(call, &bp, status, vnode, 1942 + &call->expected_version, NULL); 1943 + if (ret < 0) 1944 + return ret; 1945 + xdr_decode_YFSCallBack_raw(&bp, callback); 1946 + xdr_decode_YFSVolSync(&bp, volsync); 1947 + 1948 + _leave(" = 0 [done]"); 1949 + return 0; 1950 + } 1951 + 1952 + /* 1953 + * YFS.FetchStatus operation type 1954 + */ 1955 + static const struct afs_call_type yfs_RXYFSFetchStatus = { 1956 + .name = "YFS.FetchStatus", 1957 + .op = yfs_FS_FetchStatus, 1958 + .deliver = yfs_deliver_fs_fetch_status, 1959 + .destructor = afs_flat_call_destructor, 1960 + }; 1961 + 1962 + /* 1963 + * Fetch the status information for a fid without needing a vnode handle. 1964 + */ 1965 + int yfs_fs_fetch_status(struct afs_fs_cursor *fc, 1966 + struct afs_net *net, 1967 + struct afs_fid *fid, 1968 + struct afs_file_status *status, 1969 + struct afs_callback *callback, 1970 + struct afs_volsync *volsync) 1971 + { 1972 + struct afs_call *call; 1973 + __be32 *bp; 1974 + 1975 + _enter(",%x,{%llx:%llu},,", 1976 + key_serial(fc->key), fid->vid, fid->vnode); 1977 + 1978 + call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus, 1979 + sizeof(__be32) * 2 + 1980 + sizeof(struct yfs_xdr_YFSFid), 1981 + sizeof(struct yfs_xdr_YFSFetchStatus) + 1982 + sizeof(struct yfs_xdr_YFSCallBack) + 1983 + sizeof(struct yfs_xdr_YFSVolSync)); 1984 + if (!call) { 1985 + fc->ac.error = -ENOMEM; 1986 + return -ENOMEM; 1987 + } 1988 + 1989 + call->key = fc->key; 1990 + call->reply[0] = NULL; /* vnode for fid[0] */ 1991 + call->reply[1] = status; 1992 + call->reply[2] = callback; 1993 + call->reply[3] = volsync; 1994 + call->expected_version = 1; /* vnode->status.data_version */ 1995 + 1996 + /* marshall the parameters */ 1997 + bp = call->request; 1998 + bp = xdr_encode_u32(bp, YFSFETCHSTATUS); 1999 + bp = xdr_encode_u32(bp, 0); /* RPC flags */ 2000 + bp = xdr_encode_YFSFid(bp, fid); 2001 + yfs_check_req(call, bp); 2002 + 2003 + call->cb_break = fc->cb_break; 2004 + afs_use_fs_server(call, fc->cbi); 2005 + trace_afs_make_fs_call(call, fid); 2006 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 2007 + } 2008 + 2009 + /* 2010 + * Deliver reply data to an YFS.InlineBulkStatus call 2011 + */ 2012 + static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call) 2013 + { 2014 + struct afs_file_status *statuses; 2015 + struct afs_callback *callbacks; 2016 + struct afs_vnode *vnode = call->reply[0]; 2017 + const __be32 *bp; 2018 + u32 tmp; 2019 + int ret; 2020 + 2021 + _enter("{%u}", call->unmarshall); 2022 + 2023 + switch (call->unmarshall) { 2024 + case 0: 2025 + afs_extract_to_tmp(call); 2026 + call->unmarshall++; 2027 + 2028 + /* Extract the file status count and array in two steps */ 2029 + case 1: 2030 + _debug("extract status count"); 2031 + ret = afs_extract_data(call, true); 2032 + if (ret < 0) 2033 + return ret; 2034 + 2035 + tmp = ntohl(call->tmp); 2036 + _debug("status count: %u/%u", tmp, call->count2); 2037 + if (tmp != call->count2) 2038 + return afs_protocol_error(call, -EBADMSG, 2039 + afs_eproto_ibulkst_count); 2040 + 2041 + call->count = 0; 2042 + call->unmarshall++; 2043 + more_counts: 2044 + afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus)); 2045 + 2046 + case 2: 2047 + _debug("extract status array %u", call->count); 2048 + ret = afs_extract_data(call, true); 2049 + if (ret < 0) 2050 + return ret; 2051 + 2052 + bp = call->buffer; 2053 + statuses = call->reply[1]; 2054 + ret = yfs_decode_status(call, &bp, &statuses[call->count], 2055 + call->count == 0 ? vnode : NULL, 2056 + NULL, NULL); 2057 + if (ret < 0) 2058 + return ret; 2059 + 2060 + call->count++; 2061 + if (call->count < call->count2) 2062 + goto more_counts; 2063 + 2064 + call->count = 0; 2065 + call->unmarshall++; 2066 + afs_extract_to_tmp(call); 2067 + 2068 + /* Extract the callback count and array in two steps */ 2069 + case 3: 2070 + _debug("extract CB count"); 2071 + ret = afs_extract_data(call, true); 2072 + if (ret < 0) 2073 + return ret; 2074 + 2075 + tmp = ntohl(call->tmp); 2076 + _debug("CB count: %u", tmp); 2077 + if (tmp != call->count2) 2078 + return afs_protocol_error(call, -EBADMSG, 2079 + afs_eproto_ibulkst_cb_count); 2080 + call->count = 0; 2081 + call->unmarshall++; 2082 + more_cbs: 2083 + afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack)); 2084 + 2085 + case 4: 2086 + _debug("extract CB array"); 2087 + ret = afs_extract_data(call, true); 2088 + if (ret < 0) 2089 + return ret; 2090 + 2091 + _debug("unmarshall CB array"); 2092 + bp = call->buffer; 2093 + callbacks = call->reply[2]; 2094 + xdr_decode_YFSCallBack_raw(&bp, &callbacks[call->count]); 2095 + statuses = call->reply[1]; 2096 + if (call->count == 0 && vnode && statuses[0].abort_code == 0) { 2097 + bp = call->buffer; 2098 + xdr_decode_YFSCallBack(call, vnode, &bp); 2099 + } 2100 + call->count++; 2101 + if (call->count < call->count2) 2102 + goto more_cbs; 2103 + 2104 + afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync)); 2105 + call->unmarshall++; 2106 + 2107 + case 5: 2108 + ret = afs_extract_data(call, false); 2109 + if (ret < 0) 2110 + return ret; 2111 + 2112 + bp = call->buffer; 2113 + xdr_decode_YFSVolSync(&bp, call->reply[3]); 2114 + 2115 + call->unmarshall++; 2116 + 2117 + case 6: 2118 + break; 2119 + } 2120 + 2121 + _leave(" = 0 [done]"); 2122 + return 0; 2123 + } 2124 + 2125 + /* 2126 + * FS.InlineBulkStatus operation type 2127 + */ 2128 + static const struct afs_call_type yfs_RXYFSInlineBulkStatus = { 2129 + .name = "YFS.InlineBulkStatus", 2130 + .op = yfs_FS_InlineBulkStatus, 2131 + .deliver = yfs_deliver_fs_inline_bulk_status, 2132 + .destructor = afs_flat_call_destructor, 2133 + }; 2134 + 2135 + /* 2136 + * Fetch the status information for up to 1024 files 2137 + */ 2138 + int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc, 2139 + struct afs_net *net, 2140 + struct afs_fid *fids, 2141 + struct afs_file_status *statuses, 2142 + struct afs_callback *callbacks, 2143 + unsigned int nr_fids, 2144 + struct afs_volsync *volsync) 2145 + { 2146 + struct afs_call *call; 2147 + __be32 *bp; 2148 + int i; 2149 + 2150 + _enter(",%x,{%llx:%llu},%u", 2151 + key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids); 2152 + 2153 + call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus, 2154 + sizeof(__be32) + 2155 + sizeof(__be32) + 2156 + sizeof(__be32) + 2157 + sizeof(struct yfs_xdr_YFSFid) * nr_fids, 2158 + sizeof(struct yfs_xdr_YFSFetchStatus)); 2159 + if (!call) { 2160 + fc->ac.error = -ENOMEM; 2161 + return -ENOMEM; 2162 + } 2163 + 2164 + call->key = fc->key; 2165 + call->reply[0] = NULL; /* vnode for fid[0] */ 2166 + call->reply[1] = statuses; 2167 + call->reply[2] = callbacks; 2168 + call->reply[3] = volsync; 2169 + call->count2 = nr_fids; 2170 + 2171 + /* marshall the parameters */ 2172 + bp = call->request; 2173 + bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS); 2174 + bp = xdr_encode_u32(bp, 0); /* RPCFlags */ 2175 + bp = xdr_encode_u32(bp, nr_fids); 2176 + for (i = 0; i < nr_fids; i++) 2177 + bp = xdr_encode_YFSFid(bp, &fids[i]); 2178 + yfs_check_req(call, bp); 2179 + 2180 + call->cb_break = fc->cb_break; 2181 + afs_use_fs_server(call, fc->cbi); 2182 + trace_afs_make_fs_call(call, &fids[0]); 2183 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 2184 + }
+1 -1
fs/block_dev.c
··· 349 349 350 350 dio->size = 0; 351 351 dio->multi_bio = false; 352 - dio->should_dirty = is_read && (iter->type == ITER_IOVEC); 352 + dio->should_dirty = is_read && iter_is_iovec(iter); 353 353 354 354 blk_start_plug(&plug); 355 355 for (;;) {
+4 -5
fs/ceph/file.c
··· 615 615 616 616 more = len < iov_iter_count(to); 617 617 618 - if (unlikely(to->type & ITER_PIPE)) { 618 + if (unlikely(iov_iter_is_pipe(to))) { 619 619 ret = iov_iter_get_pages_alloc(to, &pages, len, 620 620 &page_off); 621 621 if (ret <= 0) { ··· 662 662 ret += zlen; 663 663 } 664 664 665 - if (unlikely(to->type & ITER_PIPE)) { 665 + if (unlikely(iov_iter_is_pipe(to))) { 666 666 if (ret > 0) { 667 667 iov_iter_advance(to, ret); 668 668 off += ret; ··· 815 815 aio_req->total_len = rc + zlen; 816 816 } 817 817 818 - iov_iter_bvec(&i, ITER_BVEC, osd_data->bvec_pos.bvecs, 818 + iov_iter_bvec(&i, READ, osd_data->bvec_pos.bvecs, 819 819 osd_data->num_bvecs, 820 820 osd_data->bvec_pos.iter.bi_size); 821 821 iov_iter_advance(&i, rc); ··· 1038 1038 int zlen = min_t(size_t, len - ret, 1039 1039 size - pos - ret); 1040 1040 1041 - iov_iter_bvec(&i, ITER_BVEC, bvecs, num_pages, 1042 - len); 1041 + iov_iter_bvec(&i, READ, bvecs, num_pages, len); 1043 1042 iov_iter_advance(&i, ret); 1044 1043 iov_iter_zero(zlen, &i); 1045 1044 ret += zlen;
+2 -2
fs/cifs/connect.c
··· 589 589 { 590 590 struct msghdr smb_msg; 591 591 struct kvec iov = {.iov_base = buf, .iov_len = to_read}; 592 - iov_iter_kvec(&smb_msg.msg_iter, READ | ITER_KVEC, &iov, 1, to_read); 592 + iov_iter_kvec(&smb_msg.msg_iter, READ, &iov, 1, to_read); 593 593 594 594 return cifs_readv_from_socket(server, &smb_msg); 595 595 } ··· 601 601 struct msghdr smb_msg; 602 602 struct bio_vec bv = { 603 603 .bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; 604 - iov_iter_bvec(&smb_msg.msg_iter, READ | ITER_BVEC, &bv, 1, to_read); 604 + iov_iter_bvec(&smb_msg.msg_iter, READ, &bv, 1, to_read); 605 605 return cifs_readv_from_socket(server, &smb_msg); 606 606 } 607 607
+2 -2
fs/cifs/file.c
··· 3004 3004 size_t copy = min_t(size_t, remaining, PAGE_SIZE); 3005 3005 size_t written; 3006 3006 3007 - if (unlikely(iter->type & ITER_PIPE)) { 3007 + if (unlikely(iov_iter_is_pipe(iter))) { 3008 3008 void *addr = kmap_atomic(page); 3009 3009 3010 3010 written = copy_to_iter(addr, copy, iter); ··· 3316 3316 if (!is_sync_kiocb(iocb)) 3317 3317 ctx->iocb = iocb; 3318 3318 3319 - if (to->type == ITER_IOVEC) 3319 + if (iter_is_iovec(to)) 3320 3320 ctx->should_dirty = true; 3321 3321 3322 3322 rc = setup_aio_ctx_iter(ctx, to, READ);
+2 -2
fs/cifs/misc.c
··· 788 788 struct page **pages = NULL; 789 789 struct bio_vec *bv = NULL; 790 790 791 - if (iter->type & ITER_KVEC) { 791 + if (iov_iter_is_kvec(iter)) { 792 792 memcpy(&ctx->iter, iter, sizeof(struct iov_iter)); 793 793 ctx->len = count; 794 794 iov_iter_advance(iter, count); ··· 859 859 ctx->bv = bv; 860 860 ctx->len = saved_len - count; 861 861 ctx->npages = npages; 862 - iov_iter_bvec(&ctx->iter, ITER_BVEC | rw, ctx->bv, npages, ctx->len); 862 + iov_iter_bvec(&ctx->iter, rw, ctx->bv, npages, ctx->len); 863 863 return 0; 864 864 } 865 865
+2 -2
fs/cifs/smb2ops.c
··· 3152 3152 return 0; 3153 3153 } 3154 3154 3155 - iov_iter_bvec(&iter, WRITE | ITER_BVEC, bvec, npages, data_len); 3155 + iov_iter_bvec(&iter, WRITE, bvec, npages, data_len); 3156 3156 } else if (buf_len >= data_offset + data_len) { 3157 3157 /* read response payload is in buf */ 3158 3158 WARN_ONCE(npages > 0, "read data can be either in buf or in pages"); 3159 3159 iov.iov_base = buf + data_offset; 3160 3160 iov.iov_len = data_len; 3161 - iov_iter_kvec(&iter, WRITE | ITER_KVEC, &iov, 1, data_len); 3161 + iov_iter_kvec(&iter, WRITE, &iov, 1, data_len); 3162 3162 } else { 3163 3163 /* read response payload cannot be in both buf and pages */ 3164 3164 WARN_ONCE(1, "buf can not contain only a part of read data");
+13 -4
fs/cifs/smbdirect.c
··· 2054 2054 2055 2055 info->smbd_recv_pending++; 2056 2056 2057 - switch (msg->msg_iter.type) { 2058 - case READ | ITER_KVEC: 2057 + if (iov_iter_rw(&msg->msg_iter) == WRITE) { 2058 + /* It's a bug in upper layer to get there */ 2059 + cifs_dbg(VFS, "CIFS: invalid msg iter dir %u\n", 2060 + iov_iter_rw(&msg->msg_iter)); 2061 + rc = -EINVAL; 2062 + goto out; 2063 + } 2064 + 2065 + switch (iov_iter_type(&msg->msg_iter)) { 2066 + case ITER_KVEC: 2059 2067 buf = msg->msg_iter.kvec->iov_base; 2060 2068 to_read = msg->msg_iter.kvec->iov_len; 2061 2069 rc = smbd_recv_buf(info, buf, to_read); 2062 2070 break; 2063 2071 2064 - case READ | ITER_BVEC: 2072 + case ITER_BVEC: 2065 2073 page = msg->msg_iter.bvec->bv_page; 2066 2074 page_offset = msg->msg_iter.bvec->bv_offset; 2067 2075 to_read = msg->msg_iter.bvec->bv_len; ··· 2079 2071 default: 2080 2072 /* It's a bug in upper layer to get there */ 2081 2073 cifs_dbg(VFS, "CIFS: invalid msg type %d\n", 2082 - msg->msg_iter.type); 2074 + iov_iter_type(&msg->msg_iter)); 2083 2075 rc = -EINVAL; 2084 2076 } 2085 2077 2078 + out: 2086 2079 info->smbd_recv_pending--; 2087 2080 wake_up(&info->wait_smbd_recv_pending); 2088 2081
+3 -5
fs/cifs/transport.c
··· 316 316 .iov_base = &rfc1002_marker, 317 317 .iov_len = 4 318 318 }; 319 - iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, &hiov, 320 - 1, 4); 319 + iov_iter_kvec(&smb_msg.msg_iter, WRITE, &hiov, 1, 4); 321 320 rc = smb_send_kvec(server, &smb_msg, &sent); 322 321 if (rc < 0) 323 322 goto uncork; ··· 337 338 size += iov[i].iov_len; 338 339 } 339 340 340 - iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, 341 - iov, n_vec, size); 341 + iov_iter_kvec(&smb_msg.msg_iter, WRITE, iov, n_vec, size); 342 342 343 343 rc = smb_send_kvec(server, &smb_msg, &sent); 344 344 if (rc < 0) ··· 353 355 rqst_page_get_length(&rqst[j], i, &bvec.bv_len, 354 356 &bvec.bv_offset); 355 357 356 - iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC, 358 + iov_iter_bvec(&smb_msg.msg_iter, WRITE, 357 359 &bvec, 1, bvec.bv_len); 358 360 rc = smb_send_kvec(server, &smb_msg, &sent); 359 361 if (rc < 0)
+1 -1
fs/direct-io.c
··· 1313 1313 spin_lock_init(&dio->bio_lock); 1314 1314 dio->refcount = 1; 1315 1315 1316 - dio->should_dirty = (iter->type == ITER_IOVEC); 1316 + dio->should_dirty = iter_is_iovec(iter) && iov_iter_rw(iter) == READ; 1317 1317 sdio.iter = iter; 1318 1318 sdio.final_block_in_request = end >> blkbits; 1319 1319
+1 -1
fs/dlm/lowcomms.c
··· 674 674 nvec = 2; 675 675 } 676 676 len = iov[0].iov_len + iov[1].iov_len; 677 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, nvec, len); 677 + iov_iter_kvec(&msg.msg_iter, READ, iov, nvec, len); 678 678 679 679 r = ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT | MSG_NOSIGNAL); 680 680 if (ret <= 0)
+1 -1
fs/fuse/file.c
··· 1275 1275 ssize_t ret = 0; 1276 1276 1277 1277 /* Special case for kernel I/O: can copy directly into the buffer */ 1278 - if (ii->type & ITER_KVEC) { 1278 + if (iov_iter_is_kvec(ii)) { 1279 1279 unsigned long user_addr = fuse_get_user_addr(ii); 1280 1280 size_t frag_size = fuse_get_frag_size(ii, *nbytesp); 1281 1281
+1 -1
fs/iomap.c
··· 1795 1795 if (pos >= dio->i_size) 1796 1796 goto out_free_dio; 1797 1797 1798 - if (iter->type == ITER_IOVEC) 1798 + if (iter_is_iovec(iter) && iov_iter_rw(iter) == READ) 1799 1799 dio->flags |= IOMAP_DIO_DIRTY; 1800 1800 } else { 1801 1801 flags |= IOMAP_WRITE;
+2 -2
fs/nfsd/vfs.c
··· 923 923 int host_err; 924 924 925 925 trace_nfsd_read_vector(rqstp, fhp, offset, *count); 926 - iov_iter_kvec(&iter, READ | ITER_KVEC, vec, vlen, *count); 926 + iov_iter_kvec(&iter, READ, vec, vlen, *count); 927 927 host_err = vfs_iter_read(file, &iter, &offset, 0); 928 928 return nfsd_finish_read(rqstp, fhp, file, offset, count, host_err); 929 929 } ··· 999 999 if (stable && !use_wgather) 1000 1000 flags |= RWF_SYNC; 1001 1001 1002 - iov_iter_kvec(&iter, WRITE | ITER_KVEC, vec, vlen, *cnt); 1002 + iov_iter_kvec(&iter, WRITE, vec, vlen, *cnt); 1003 1003 host_err = vfs_iter_write(file, &iter, &pos, flags); 1004 1004 if (host_err < 0) 1005 1005 goto out_nfserr;
+1 -1
fs/ocfs2/cluster/tcp.c
··· 916 916 { 917 917 struct kvec vec = { .iov_len = len, .iov_base = data, }; 918 918 struct msghdr msg = { .msg_flags = MSG_DONTWAIT, }; 919 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, len); 919 + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, len); 920 920 return sock_recvmsg(sock, &msg, MSG_DONTWAIT); 921 921 } 922 922
+1 -1
fs/orangefs/inode.c
··· 25 25 struct iov_iter to; 26 26 struct bio_vec bv = {.bv_page = page, .bv_len = PAGE_SIZE}; 27 27 28 - iov_iter_bvec(&to, ITER_BVEC | READ, &bv, 1, PAGE_SIZE); 28 + iov_iter_bvec(&to, READ, &bv, 1, PAGE_SIZE); 29 29 30 30 gossip_debug(GOSSIP_INODE_DEBUG, 31 31 "orangefs_readpage called with page %p\n",
+3 -4
fs/splice.c
··· 301 301 struct kiocb kiocb; 302 302 int idx, ret; 303 303 304 - iov_iter_pipe(&to, ITER_PIPE | READ, pipe, len); 304 + iov_iter_pipe(&to, READ, pipe, len); 305 305 idx = to.idx; 306 306 init_sync_kiocb(&kiocb, in); 307 307 kiocb.ki_pos = *ppos; ··· 386 386 */ 387 387 offset = *ppos & ~PAGE_MASK; 388 388 389 - iov_iter_pipe(&to, ITER_PIPE | READ, pipe, len + offset); 389 + iov_iter_pipe(&to, READ, pipe, len + offset); 390 390 391 391 res = iov_iter_get_pages_alloc(&to, &pages, len + offset, &base); 392 392 if (res <= 0) ··· 745 745 left -= this_len; 746 746 } 747 747 748 - iov_iter_bvec(&from, ITER_BVEC | WRITE, array, n, 749 - sd.total_len - left); 748 + iov_iter_bvec(&from, WRITE, array, n, sd.total_len - left); 750 749 ret = vfs_iter_write(out, &from, &sd.pos, 0); 751 750 if (ret <= 0) 752 751 break;
+45 -20
include/linux/uio.h
··· 21 21 size_t iov_len; 22 22 }; 23 23 24 - enum { 24 + enum iter_type { 25 25 ITER_IOVEC = 0, 26 26 ITER_KVEC = 2, 27 27 ITER_BVEC = 4, 28 28 ITER_PIPE = 8, 29 + ITER_DISCARD = 16, 29 30 }; 30 31 31 32 struct iov_iter { 32 - int type; 33 + unsigned int type; 33 34 size_t iov_offset; 34 35 size_t count; 35 36 union { ··· 47 46 }; 48 47 }; 49 48 }; 49 + 50 + static inline enum iter_type iov_iter_type(const struct iov_iter *i) 51 + { 52 + return i->type & ~(READ | WRITE); 53 + } 54 + 55 + static inline bool iter_is_iovec(const struct iov_iter *i) 56 + { 57 + return iov_iter_type(i) == ITER_IOVEC; 58 + } 59 + 60 + static inline bool iov_iter_is_kvec(const struct iov_iter *i) 61 + { 62 + return iov_iter_type(i) == ITER_KVEC; 63 + } 64 + 65 + static inline bool iov_iter_is_bvec(const struct iov_iter *i) 66 + { 67 + return iov_iter_type(i) == ITER_BVEC; 68 + } 69 + 70 + static inline bool iov_iter_is_pipe(const struct iov_iter *i) 71 + { 72 + return iov_iter_type(i) == ITER_PIPE; 73 + } 74 + 75 + static inline bool iov_iter_is_discard(const struct iov_iter *i) 76 + { 77 + return iov_iter_type(i) == ITER_DISCARD; 78 + } 79 + 80 + static inline unsigned char iov_iter_rw(const struct iov_iter *i) 81 + { 82 + return i->type & (READ | WRITE); 83 + } 50 84 51 85 /* 52 86 * Total number of bytes covered by an iovec. ··· 110 74 } 111 75 112 76 #define iov_for_each(iov, iter, start) \ 113 - if (!((start).type & (ITER_BVEC | ITER_PIPE))) \ 77 + if (iov_iter_type(start) == ITER_IOVEC || \ 78 + iov_iter_type(start) == ITER_KVEC) \ 114 79 for (iter = (start); \ 115 80 (iter).count && \ 116 81 ((iov = iov_iter_iovec(&(iter))), 1); \ ··· 218 181 size_t iov_iter_zero(size_t bytes, struct iov_iter *); 219 182 unsigned long iov_iter_alignment(const struct iov_iter *i); 220 183 unsigned long iov_iter_gap_alignment(const struct iov_iter *i); 221 - void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov, 184 + void iov_iter_init(struct iov_iter *i, unsigned int direction, const struct iovec *iov, 222 185 unsigned long nr_segs, size_t count); 223 - void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec, 186 + void iov_iter_kvec(struct iov_iter *i, unsigned int direction, const struct kvec *kvec, 224 187 unsigned long nr_segs, size_t count); 225 - void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec, 188 + void iov_iter_bvec(struct iov_iter *i, unsigned int direction, const struct bio_vec *bvec, 226 189 unsigned long nr_segs, size_t count); 227 - void iov_iter_pipe(struct iov_iter *i, int direction, struct pipe_inode_info *pipe, 190 + void iov_iter_pipe(struct iov_iter *i, unsigned int direction, struct pipe_inode_info *pipe, 228 191 size_t count); 192 + void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count); 229 193 ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, 230 194 size_t maxsize, unsigned maxpages, size_t *start); 231 195 ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, ··· 239 201 { 240 202 return i->count; 241 203 } 242 - 243 - static inline bool iter_is_iovec(const struct iov_iter *i) 244 - { 245 - return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE)); 246 - } 247 - 248 - /* 249 - * Get one of READ or WRITE out of iter->type without any other flags OR'd in 250 - * with it. 251 - * 252 - * The ?: is just for type safety. 253 - */ 254 - #define iov_iter_rw(i) ((0 ? (struct iov_iter *)0 : (i))->type & (READ | WRITE)) 255 204 256 205 /* 257 206 * Cap the iov_iter by given limit; note that the second argument is
+195 -18
include/trace/events/afs.h
··· 54 54 afs_FS_StoreData64 = 65538, /* AFS Store file data */ 55 55 afs_FS_GiveUpAllCallBacks = 65539, /* AFS Give up all our callbacks on a server */ 56 56 afs_FS_GetCapabilities = 65540, /* AFS Get FS server capabilities */ 57 + 58 + yfs_FS_FetchData = 130, /* YFS Fetch file data */ 59 + yfs_FS_FetchACL = 64131, /* YFS Fetch file ACL */ 60 + yfs_FS_FetchStatus = 64132, /* YFS Fetch file status */ 61 + yfs_FS_StoreACL = 64134, /* YFS Store file ACL */ 62 + yfs_FS_StoreStatus = 64135, /* YFS Store file status */ 63 + yfs_FS_RemoveFile = 64136, /* YFS Remove a file */ 64 + yfs_FS_CreateFile = 64137, /* YFS Create a file */ 65 + yfs_FS_Rename = 64138, /* YFS Rename or move a file or directory */ 66 + yfs_FS_Symlink = 64139, /* YFS Create a symbolic link */ 67 + yfs_FS_Link = 64140, /* YFS Create a hard link */ 68 + yfs_FS_MakeDir = 64141, /* YFS Create a directory */ 69 + yfs_FS_RemoveDir = 64142, /* YFS Remove a directory */ 70 + yfs_FS_GetVolumeStatus = 64149, /* YFS Get volume status information */ 71 + yfs_FS_SetVolumeStatus = 64150, /* YFS Set volume status information */ 72 + yfs_FS_SetLock = 64156, /* YFS Request a file lock */ 73 + yfs_FS_ExtendLock = 64157, /* YFS Extend a file lock */ 74 + yfs_FS_ReleaseLock = 64158, /* YFS Release a file lock */ 75 + yfs_FS_Lookup = 64161, /* YFS lookup file in directory */ 76 + yfs_FS_FlushCPS = 64165, 77 + yfs_FS_FetchOpaqueACL = 64168, 78 + yfs_FS_WhoAmI = 64170, 79 + yfs_FS_RemoveACL = 64171, 80 + yfs_FS_RemoveFile2 = 64173, 81 + yfs_FS_StoreOpaqueACL2 = 64174, 82 + yfs_FS_InlineBulkStatus = 64536, /* YFS Fetch multiple file statuses with errors */ 83 + yfs_FS_FetchData64 = 64537, /* YFS Fetch file data */ 84 + yfs_FS_StoreData64 = 64538, /* YFS Store file data */ 85 + yfs_FS_UpdateSymlink = 64540, 57 86 }; 58 87 59 88 enum afs_vl_operation { ··· 111 82 afs_edit_dir_for_rmdir, 112 83 afs_edit_dir_for_symlink, 113 84 afs_edit_dir_for_unlink, 85 + }; 86 + 87 + enum afs_eproto_cause { 88 + afs_eproto_bad_status, 89 + afs_eproto_cb_count, 90 + afs_eproto_cb_fid_count, 91 + afs_eproto_file_type, 92 + afs_eproto_ibulkst_cb_count, 93 + afs_eproto_ibulkst_count, 94 + afs_eproto_motd_len, 95 + afs_eproto_offline_msg_len, 96 + afs_eproto_volname_len, 97 + afs_eproto_yvl_fsendpt4_len, 98 + afs_eproto_yvl_fsendpt6_len, 99 + afs_eproto_yvl_fsendpt_num, 100 + afs_eproto_yvl_fsendpt_type, 101 + afs_eproto_yvl_vlendpt4_len, 102 + afs_eproto_yvl_vlendpt6_len, 103 + afs_eproto_yvl_vlendpt_type, 104 + }; 105 + 106 + enum afs_io_error { 107 + afs_io_error_cm_reply, 108 + afs_io_error_extract, 109 + afs_io_error_fs_probe_fail, 110 + afs_io_error_vl_lookup_fail, 111 + afs_io_error_vl_probe_fail, 112 + }; 113 + 114 + enum afs_file_error { 115 + afs_file_error_dir_bad_magic, 116 + afs_file_error_dir_big, 117 + afs_file_error_dir_missing_page, 118 + afs_file_error_dir_over_end, 119 + afs_file_error_dir_small, 120 + afs_file_error_dir_unmarked_ext, 121 + afs_file_error_mntpt, 122 + afs_file_error_writeback_fail, 114 123 }; 115 124 116 125 #endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */ ··· 186 119 EM(afs_FS_FetchData64, "FS.FetchData64") \ 187 120 EM(afs_FS_StoreData64, "FS.StoreData64") \ 188 121 EM(afs_FS_GiveUpAllCallBacks, "FS.GiveUpAllCallBacks") \ 189 - E_(afs_FS_GetCapabilities, "FS.GetCapabilities") 122 + EM(afs_FS_GetCapabilities, "FS.GetCapabilities") \ 123 + EM(yfs_FS_FetchACL, "YFS.FetchACL") \ 124 + EM(yfs_FS_FetchStatus, "YFS.FetchStatus") \ 125 + EM(yfs_FS_StoreACL, "YFS.StoreACL") \ 126 + EM(yfs_FS_StoreStatus, "YFS.StoreStatus") \ 127 + EM(yfs_FS_RemoveFile, "YFS.RemoveFile") \ 128 + EM(yfs_FS_CreateFile, "YFS.CreateFile") \ 129 + EM(yfs_FS_Rename, "YFS.Rename") \ 130 + EM(yfs_FS_Symlink, "YFS.Symlink") \ 131 + EM(yfs_FS_Link, "YFS.Link") \ 132 + EM(yfs_FS_MakeDir, "YFS.MakeDir") \ 133 + EM(yfs_FS_RemoveDir, "YFS.RemoveDir") \ 134 + EM(yfs_FS_GetVolumeStatus, "YFS.GetVolumeStatus") \ 135 + EM(yfs_FS_SetVolumeStatus, "YFS.SetVolumeStatus") \ 136 + EM(yfs_FS_SetLock, "YFS.SetLock") \ 137 + EM(yfs_FS_ExtendLock, "YFS.ExtendLock") \ 138 + EM(yfs_FS_ReleaseLock, "YFS.ReleaseLock") \ 139 + EM(yfs_FS_Lookup, "YFS.Lookup") \ 140 + EM(yfs_FS_FlushCPS, "YFS.FlushCPS") \ 141 + EM(yfs_FS_FetchOpaqueACL, "YFS.FetchOpaqueACL") \ 142 + EM(yfs_FS_WhoAmI, "YFS.WhoAmI") \ 143 + EM(yfs_FS_RemoveACL, "YFS.RemoveACL") \ 144 + EM(yfs_FS_RemoveFile2, "YFS.RemoveFile2") \ 145 + EM(yfs_FS_StoreOpaqueACL2, "YFS.StoreOpaqueACL2") \ 146 + EM(yfs_FS_InlineBulkStatus, "YFS.InlineBulkStatus") \ 147 + EM(yfs_FS_FetchData64, "YFS.FetchData64") \ 148 + EM(yfs_FS_StoreData64, "YFS.StoreData64") \ 149 + E_(yfs_FS_UpdateSymlink, "YFS.UpdateSymlink") 190 150 191 151 #define afs_vl_operations \ 192 152 EM(afs_VL_GetEntryByNameU, "VL.GetEntryByNameU") \ ··· 240 146 EM(afs_edit_dir_for_symlink, "Symlnk") \ 241 147 E_(afs_edit_dir_for_unlink, "Unlink") 242 148 149 + #define afs_eproto_causes \ 150 + EM(afs_eproto_bad_status, "BadStatus") \ 151 + EM(afs_eproto_cb_count, "CbCount") \ 152 + EM(afs_eproto_cb_fid_count, "CbFidCount") \ 153 + EM(afs_eproto_file_type, "FileTYpe") \ 154 + EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \ 155 + EM(afs_eproto_ibulkst_count, "IBS.FidCount") \ 156 + EM(afs_eproto_motd_len, "MotdLen") \ 157 + EM(afs_eproto_offline_msg_len, "OfflineMsgLen") \ 158 + EM(afs_eproto_volname_len, "VolNameLen") \ 159 + EM(afs_eproto_yvl_fsendpt4_len, "YVL.FsEnd4Len") \ 160 + EM(afs_eproto_yvl_fsendpt6_len, "YVL.FsEnd6Len") \ 161 + EM(afs_eproto_yvl_fsendpt_num, "YVL.FsEndCount") \ 162 + EM(afs_eproto_yvl_fsendpt_type, "YVL.FsEndType") \ 163 + EM(afs_eproto_yvl_vlendpt4_len, "YVL.VlEnd4Len") \ 164 + EM(afs_eproto_yvl_vlendpt6_len, "YVL.VlEnd6Len") \ 165 + E_(afs_eproto_yvl_vlendpt_type, "YVL.VlEndType") 166 + 167 + #define afs_io_errors \ 168 + EM(afs_io_error_cm_reply, "CM_REPLY") \ 169 + EM(afs_io_error_extract, "EXTRACT") \ 170 + EM(afs_io_error_fs_probe_fail, "FS_PROBE_FAIL") \ 171 + EM(afs_io_error_vl_lookup_fail, "VL_LOOKUP_FAIL") \ 172 + E_(afs_io_error_vl_probe_fail, "VL_PROBE_FAIL") 173 + 174 + #define afs_file_errors \ 175 + EM(afs_file_error_dir_bad_magic, "DIR_BAD_MAGIC") \ 176 + EM(afs_file_error_dir_big, "DIR_BIG") \ 177 + EM(afs_file_error_dir_missing_page, "DIR_MISSING_PAGE") \ 178 + EM(afs_file_error_dir_over_end, "DIR_ENT_OVER_END") \ 179 + EM(afs_file_error_dir_small, "DIR_SMALL") \ 180 + EM(afs_file_error_dir_unmarked_ext, "DIR_UNMARKED_EXT") \ 181 + EM(afs_file_error_mntpt, "MNTPT_READ_FAILED") \ 182 + E_(afs_file_error_writeback_fail, "WRITEBACK_FAILED") 243 183 244 184 /* 245 185 * Export enum symbols via userspace. ··· 288 160 afs_vl_operations; 289 161 afs_edit_dir_ops; 290 162 afs_edit_dir_reasons; 163 + afs_eproto_causes; 164 + afs_io_errors; 165 + afs_file_errors; 291 166 292 167 /* 293 168 * Now redefine the EM() and E_() macros to map the enums to the strings that ··· 301 170 #define EM(a, b) { a, b }, 302 171 #define E_(a, b) { a, b } 303 172 304 - TRACE_EVENT(afs_recv_data, 305 - TP_PROTO(struct afs_call *call, unsigned count, unsigned offset, 173 + TRACE_EVENT(afs_receive_data, 174 + TP_PROTO(struct afs_call *call, struct iov_iter *iter, 306 175 bool want_more, int ret), 307 176 308 - TP_ARGS(call, count, offset, want_more, ret), 177 + TP_ARGS(call, iter, want_more, ret), 309 178 310 179 TP_STRUCT__entry( 180 + __field(loff_t, remain ) 311 181 __field(unsigned int, call ) 312 182 __field(enum afs_call_state, state ) 313 - __field(unsigned int, count ) 314 - __field(unsigned int, offset ) 315 183 __field(unsigned short, unmarshall ) 316 184 __field(bool, want_more ) 317 185 __field(int, ret ) ··· 320 190 __entry->call = call->debug_id; 321 191 __entry->state = call->state; 322 192 __entry->unmarshall = call->unmarshall; 323 - __entry->count = count; 324 - __entry->offset = offset; 193 + __entry->remain = iov_iter_count(iter); 325 194 __entry->want_more = want_more; 326 195 __entry->ret = ret; 327 196 ), 328 197 329 - TP_printk("c=%08x s=%u u=%u %u/%u wm=%u ret=%d", 198 + TP_printk("c=%08x r=%llu u=%u w=%u s=%u ret=%d", 330 199 __entry->call, 331 - __entry->state, __entry->unmarshall, 332 - __entry->offset, __entry->count, 333 - __entry->want_more, __entry->ret) 200 + __entry->remain, 201 + __entry->unmarshall, 202 + __entry->want_more, 203 + __entry->state, 204 + __entry->ret) 334 205 ); 335 206 336 207 TRACE_EVENT(afs_notify_call, ··· 432 301 } 433 302 ), 434 303 435 - TP_printk("c=%08x %06x:%06x:%06x %s", 304 + TP_printk("c=%08x %06llx:%06llx:%06x %s", 436 305 __entry->call, 437 306 __entry->fid.vid, 438 307 __entry->fid.vnode, ··· 686 555 ); 687 556 688 557 TRACE_EVENT(afs_protocol_error, 689 - TP_PROTO(struct afs_call *call, int error, const void *where), 558 + TP_PROTO(struct afs_call *call, int error, enum afs_eproto_cause cause), 559 + 560 + TP_ARGS(call, error, cause), 561 + 562 + TP_STRUCT__entry( 563 + __field(unsigned int, call ) 564 + __field(int, error ) 565 + __field(enum afs_eproto_cause, cause ) 566 + ), 567 + 568 + TP_fast_assign( 569 + __entry->call = call ? call->debug_id : 0; 570 + __entry->error = error; 571 + __entry->cause = cause; 572 + ), 573 + 574 + TP_printk("c=%08x r=%d %s", 575 + __entry->call, __entry->error, 576 + __print_symbolic(__entry->cause, afs_eproto_causes)) 577 + ); 578 + 579 + TRACE_EVENT(afs_io_error, 580 + TP_PROTO(unsigned int call, int error, enum afs_io_error where), 690 581 691 582 TP_ARGS(call, error, where), 692 583 693 584 TP_STRUCT__entry( 694 585 __field(unsigned int, call ) 695 586 __field(int, error ) 696 - __field(const void *, where ) 587 + __field(enum afs_io_error, where ) 697 588 ), 698 589 699 590 TP_fast_assign( 700 - __entry->call = call ? call->debug_id : 0; 591 + __entry->call = call; 701 592 __entry->error = error; 702 593 __entry->where = where; 703 594 ), 704 595 705 - TP_printk("c=%08x r=%d sp=%pSR", 706 - __entry->call, __entry->error, __entry->where) 596 + TP_printk("c=%08x r=%d %s", 597 + __entry->call, __entry->error, 598 + __print_symbolic(__entry->where, afs_io_errors)) 599 + ); 600 + 601 + TRACE_EVENT(afs_file_error, 602 + TP_PROTO(struct afs_vnode *vnode, int error, enum afs_file_error where), 603 + 604 + TP_ARGS(vnode, error, where), 605 + 606 + TP_STRUCT__entry( 607 + __field_struct(struct afs_fid, fid ) 608 + __field(int, error ) 609 + __field(enum afs_file_error, where ) 610 + ), 611 + 612 + TP_fast_assign( 613 + __entry->fid = vnode->fid; 614 + __entry->error = error; 615 + __entry->where = where; 616 + ), 617 + 618 + TP_printk("%llx:%llx:%x r=%d %s", 619 + __entry->fid.vid, __entry->fid.vnode, __entry->fid.unique, 620 + __entry->error, 621 + __print_symbolic(__entry->where, afs_file_errors)) 707 622 ); 708 623 709 624 TRACE_EVENT(afs_cm_no_server,
+84 -41
lib/iov_iter.c
··· 83 83 const struct kvec *kvec; \ 84 84 struct kvec v; \ 85 85 iterate_kvec(i, n, v, kvec, skip, (K)) \ 86 + } else if (unlikely(i->type & ITER_DISCARD)) { \ 86 87 } else { \ 87 88 const struct iovec *iov; \ 88 89 struct iovec v; \ ··· 115 114 } \ 116 115 i->nr_segs -= kvec - i->kvec; \ 117 116 i->kvec = kvec; \ 117 + } else if (unlikely(i->type & ITER_DISCARD)) { \ 118 + skip += n; \ 118 119 } else { \ 119 120 const struct iovec *iov; \ 120 121 struct iovec v; \ ··· 431 428 } 432 429 EXPORT_SYMBOL(iov_iter_fault_in_readable); 433 430 434 - void iov_iter_init(struct iov_iter *i, int direction, 431 + void iov_iter_init(struct iov_iter *i, unsigned int direction, 435 432 const struct iovec *iov, unsigned long nr_segs, 436 433 size_t count) 437 434 { 435 + WARN_ON(direction & ~(READ | WRITE)); 436 + direction &= READ | WRITE; 437 + 438 438 /* It will get better. Eventually... */ 439 439 if (uaccess_kernel()) { 440 - direction |= ITER_KVEC; 441 - i->type = direction; 440 + i->type = ITER_KVEC | direction; 442 441 i->kvec = (struct kvec *)iov; 443 442 } else { 444 - i->type = direction; 443 + i->type = ITER_IOVEC | direction; 445 444 i->iov = iov; 446 445 } 447 446 i->nr_segs = nr_segs; ··· 563 558 size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i) 564 559 { 565 560 const char *from = addr; 566 - if (unlikely(i->type & ITER_PIPE)) 561 + if (unlikely(iov_iter_is_pipe(i))) 567 562 return copy_pipe_to_iter(addr, bytes, i); 568 563 if (iter_is_iovec(i)) 569 564 might_fault(); ··· 663 658 const char *from = addr; 664 659 unsigned long rem, curr_addr, s_addr = (unsigned long) addr; 665 660 666 - if (unlikely(i->type & ITER_PIPE)) 661 + if (unlikely(iov_iter_is_pipe(i))) 667 662 return copy_pipe_to_iter_mcsafe(addr, bytes, i); 668 663 if (iter_is_iovec(i)) 669 664 might_fault(); ··· 697 692 size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i) 698 693 { 699 694 char *to = addr; 700 - if (unlikely(i->type & ITER_PIPE)) { 695 + if (unlikely(iov_iter_is_pipe(i))) { 701 696 WARN_ON(1); 702 697 return 0; 703 698 } ··· 717 712 bool _copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i) 718 713 { 719 714 char *to = addr; 720 - if (unlikely(i->type & ITER_PIPE)) { 715 + if (unlikely(iov_iter_is_pipe(i))) { 721 716 WARN_ON(1); 722 717 return false; 723 718 } ··· 744 739 size_t _copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i) 745 740 { 746 741 char *to = addr; 747 - if (unlikely(i->type & ITER_PIPE)) { 742 + if (unlikely(iov_iter_is_pipe(i))) { 748 743 WARN_ON(1); 749 744 return 0; 750 745 } ··· 778 773 size_t _copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i) 779 774 { 780 775 char *to = addr; 781 - if (unlikely(i->type & ITER_PIPE)) { 776 + if (unlikely(iov_iter_is_pipe(i))) { 782 777 WARN_ON(1); 783 778 return 0; 784 779 } ··· 799 794 bool _copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i) 800 795 { 801 796 char *to = addr; 802 - if (unlikely(i->type & ITER_PIPE)) { 797 + if (unlikely(iov_iter_is_pipe(i))) { 803 798 WARN_ON(1); 804 799 return false; 805 800 } ··· 841 836 size_t wanted = copy_to_iter(kaddr + offset, bytes, i); 842 837 kunmap_atomic(kaddr); 843 838 return wanted; 844 - } else if (likely(!(i->type & ITER_PIPE))) 839 + } else if (unlikely(iov_iter_is_discard(i))) 840 + return bytes; 841 + else if (likely(!iov_iter_is_pipe(i))) 845 842 return copy_page_to_iter_iovec(page, offset, bytes, i); 846 843 else 847 844 return copy_page_to_iter_pipe(page, offset, bytes, i); ··· 855 848 { 856 849 if (unlikely(!page_copy_sane(page, offset, bytes))) 857 850 return 0; 858 - if (unlikely(i->type & ITER_PIPE)) { 851 + if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 859 852 WARN_ON(1); 860 853 return 0; 861 854 } ··· 895 888 896 889 size_t iov_iter_zero(size_t bytes, struct iov_iter *i) 897 890 { 898 - if (unlikely(i->type & ITER_PIPE)) 891 + if (unlikely(iov_iter_is_pipe(i))) 899 892 return pipe_zero(bytes, i); 900 893 iterate_and_advance(i, bytes, v, 901 894 clear_user(v.iov_base, v.iov_len), ··· 915 908 kunmap_atomic(kaddr); 916 909 return 0; 917 910 } 918 - if (unlikely(i->type & ITER_PIPE)) { 911 + if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 919 912 kunmap_atomic(kaddr); 920 913 WARN_ON(1); 921 914 return 0; ··· 979 972 980 973 void iov_iter_advance(struct iov_iter *i, size_t size) 981 974 { 982 - if (unlikely(i->type & ITER_PIPE)) { 975 + if (unlikely(iov_iter_is_pipe(i))) { 983 976 pipe_advance(i, size); 977 + return; 978 + } 979 + if (unlikely(iov_iter_is_discard(i))) { 980 + i->count -= size; 984 981 return; 985 982 } 986 983 iterate_and_advance(i, size, v, 0, 0, 0) ··· 998 987 if (WARN_ON(unroll > MAX_RW_COUNT)) 999 988 return; 1000 989 i->count += unroll; 1001 - if (unlikely(i->type & ITER_PIPE)) { 990 + if (unlikely(iov_iter_is_pipe(i))) { 1002 991 struct pipe_inode_info *pipe = i->pipe; 1003 992 int idx = i->idx; 1004 993 size_t off = i->iov_offset; ··· 1022 1011 pipe_truncate(i); 1023 1012 return; 1024 1013 } 1014 + if (unlikely(iov_iter_is_discard(i))) 1015 + return; 1025 1016 if (unroll <= i->iov_offset) { 1026 1017 i->iov_offset -= unroll; 1027 1018 return; 1028 1019 } 1029 1020 unroll -= i->iov_offset; 1030 - if (i->type & ITER_BVEC) { 1021 + if (iov_iter_is_bvec(i)) { 1031 1022 const struct bio_vec *bvec = i->bvec; 1032 1023 while (1) { 1033 1024 size_t n = (--bvec)->bv_len; ··· 1062 1049 */ 1063 1050 size_t iov_iter_single_seg_count(const struct iov_iter *i) 1064 1051 { 1065 - if (unlikely(i->type & ITER_PIPE)) 1052 + if (unlikely(iov_iter_is_pipe(i))) 1066 1053 return i->count; // it is a silly place, anyway 1067 1054 if (i->nr_segs == 1) 1068 1055 return i->count; 1069 - else if (i->type & ITER_BVEC) 1056 + if (unlikely(iov_iter_is_discard(i))) 1057 + return i->count; 1058 + else if (iov_iter_is_bvec(i)) 1070 1059 return min(i->count, i->bvec->bv_len - i->iov_offset); 1071 1060 else 1072 1061 return min(i->count, i->iov->iov_len - i->iov_offset); 1073 1062 } 1074 1063 EXPORT_SYMBOL(iov_iter_single_seg_count); 1075 1064 1076 - void iov_iter_kvec(struct iov_iter *i, int direction, 1065 + void iov_iter_kvec(struct iov_iter *i, unsigned int direction, 1077 1066 const struct kvec *kvec, unsigned long nr_segs, 1078 1067 size_t count) 1079 1068 { 1080 - BUG_ON(!(direction & ITER_KVEC)); 1081 - i->type = direction; 1069 + WARN_ON(direction & ~(READ | WRITE)); 1070 + i->type = ITER_KVEC | (direction & (READ | WRITE)); 1082 1071 i->kvec = kvec; 1083 1072 i->nr_segs = nr_segs; 1084 1073 i->iov_offset = 0; ··· 1088 1073 } 1089 1074 EXPORT_SYMBOL(iov_iter_kvec); 1090 1075 1091 - void iov_iter_bvec(struct iov_iter *i, int direction, 1076 + void iov_iter_bvec(struct iov_iter *i, unsigned int direction, 1092 1077 const struct bio_vec *bvec, unsigned long nr_segs, 1093 1078 size_t count) 1094 1079 { 1095 - BUG_ON(!(direction & ITER_BVEC)); 1096 - i->type = direction; 1080 + WARN_ON(direction & ~(READ | WRITE)); 1081 + i->type = ITER_BVEC | (direction & (READ | WRITE)); 1097 1082 i->bvec = bvec; 1098 1083 i->nr_segs = nr_segs; 1099 1084 i->iov_offset = 0; ··· 1101 1086 } 1102 1087 EXPORT_SYMBOL(iov_iter_bvec); 1103 1088 1104 - void iov_iter_pipe(struct iov_iter *i, int direction, 1089 + void iov_iter_pipe(struct iov_iter *i, unsigned int direction, 1105 1090 struct pipe_inode_info *pipe, 1106 1091 size_t count) 1107 1092 { 1108 - BUG_ON(direction != ITER_PIPE); 1093 + BUG_ON(direction != READ); 1109 1094 WARN_ON(pipe->nrbufs == pipe->buffers); 1110 - i->type = direction; 1095 + i->type = ITER_PIPE | READ; 1111 1096 i->pipe = pipe; 1112 1097 i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); 1113 1098 i->iov_offset = 0; ··· 1116 1101 } 1117 1102 EXPORT_SYMBOL(iov_iter_pipe); 1118 1103 1104 + /** 1105 + * iov_iter_discard - Initialise an I/O iterator that discards data 1106 + * @i: The iterator to initialise. 1107 + * @direction: The direction of the transfer. 1108 + * @count: The size of the I/O buffer in bytes. 1109 + * 1110 + * Set up an I/O iterator that just discards everything that's written to it. 1111 + * It's only available as a READ iterator. 1112 + */ 1113 + void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count) 1114 + { 1115 + BUG_ON(direction != READ); 1116 + i->type = ITER_DISCARD | READ; 1117 + i->count = count; 1118 + i->iov_offset = 0; 1119 + } 1120 + EXPORT_SYMBOL(iov_iter_discard); 1121 + 1119 1122 unsigned long iov_iter_alignment(const struct iov_iter *i) 1120 1123 { 1121 1124 unsigned long res = 0; 1122 1125 size_t size = i->count; 1123 1126 1124 - if (unlikely(i->type & ITER_PIPE)) { 1127 + if (unlikely(iov_iter_is_pipe(i))) { 1125 1128 if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx])) 1126 1129 return size | i->iov_offset; 1127 1130 return size; ··· 1158 1125 unsigned long res = 0; 1159 1126 size_t size = i->count; 1160 1127 1161 - if (unlikely(i->type & ITER_PIPE)) { 1128 + if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 1162 1129 WARN_ON(1); 1163 1130 return ~0U; 1164 1131 } ··· 1226 1193 if (maxsize > i->count) 1227 1194 maxsize = i->count; 1228 1195 1229 - if (unlikely(i->type & ITER_PIPE)) 1196 + if (unlikely(iov_iter_is_pipe(i))) 1230 1197 return pipe_get_pages(i, pages, maxsize, maxpages, start); 1198 + if (unlikely(iov_iter_is_discard(i))) 1199 + return -EFAULT; 1200 + 1231 1201 iterate_all_kinds(i, maxsize, v, ({ 1232 1202 unsigned long addr = (unsigned long)v.iov_base; 1233 1203 size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); ··· 1241 1205 len = maxpages * PAGE_SIZE; 1242 1206 addr &= ~(PAGE_SIZE - 1); 1243 1207 n = DIV_ROUND_UP(len, PAGE_SIZE); 1244 - res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages); 1208 + res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE, pages); 1245 1209 if (unlikely(res < 0)) 1246 1210 return res; 1247 1211 return (res == n ? len : res * PAGE_SIZE) - *start; ··· 1306 1270 if (maxsize > i->count) 1307 1271 maxsize = i->count; 1308 1272 1309 - if (unlikely(i->type & ITER_PIPE)) 1273 + if (unlikely(iov_iter_is_pipe(i))) 1310 1274 return pipe_get_pages_alloc(i, pages, maxsize, start); 1275 + if (unlikely(iov_iter_is_discard(i))) 1276 + return -EFAULT; 1277 + 1311 1278 iterate_all_kinds(i, maxsize, v, ({ 1312 1279 unsigned long addr = (unsigned long)v.iov_base; 1313 1280 size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); ··· 1322 1283 p = get_pages_array(n); 1323 1284 if (!p) 1324 1285 return -ENOMEM; 1325 - res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, p); 1286 + res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE, p); 1326 1287 if (unlikely(res < 0)) { 1327 1288 kvfree(p); 1328 1289 return res; ··· 1352 1313 __wsum sum, next; 1353 1314 size_t off = 0; 1354 1315 sum = *csum; 1355 - if (unlikely(i->type & ITER_PIPE)) { 1316 + if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 1356 1317 WARN_ON(1); 1357 1318 return 0; 1358 1319 } ··· 1394 1355 __wsum sum, next; 1395 1356 size_t off = 0; 1396 1357 sum = *csum; 1397 - if (unlikely(i->type & ITER_PIPE)) { 1358 + if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 1398 1359 WARN_ON(1); 1399 1360 return false; 1400 1361 } ··· 1439 1400 __wsum sum, next; 1440 1401 size_t off = 0; 1441 1402 sum = *csum; 1442 - if (unlikely(i->type & ITER_PIPE)) { 1403 + if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { 1443 1404 WARN_ON(1); /* for now */ 1444 1405 return 0; 1445 1406 } ··· 1481 1442 1482 1443 if (!size) 1483 1444 return 0; 1445 + if (unlikely(iov_iter_is_discard(i))) 1446 + return 0; 1484 1447 1485 - if (unlikely(i->type & ITER_PIPE)) { 1448 + if (unlikely(iov_iter_is_pipe(i))) { 1486 1449 struct pipe_inode_info *pipe = i->pipe; 1487 1450 size_t off; 1488 1451 int idx; ··· 1522 1481 const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags) 1523 1482 { 1524 1483 *new = *old; 1525 - if (unlikely(new->type & ITER_PIPE)) { 1484 + if (unlikely(iov_iter_is_pipe(new))) { 1526 1485 WARN_ON(1); 1527 1486 return NULL; 1528 1487 } 1529 - if (new->type & ITER_BVEC) 1488 + if (unlikely(iov_iter_is_discard(new))) 1489 + return NULL; 1490 + if (iov_iter_is_bvec(new)) 1530 1491 return new->bvec = kmemdup(new->bvec, 1531 1492 new->nr_segs * sizeof(struct bio_vec), 1532 1493 flags);
+1 -1
mm/filemap.c
··· 2049 2049 !mapping->a_ops->is_partially_uptodate) 2050 2050 goto page_not_up_to_date; 2051 2051 /* pipes can't handle partially uptodate pages */ 2052 - if (unlikely(iter->type & ITER_PIPE)) 2052 + if (unlikely(iov_iter_is_pipe(iter))) 2053 2053 goto page_not_up_to_date; 2054 2054 if (!trylock_page(page)) 2055 2055 goto page_not_up_to_date;
+1 -1
mm/page_io.c
··· 294 294 }; 295 295 struct iov_iter from; 296 296 297 - iov_iter_bvec(&from, ITER_BVEC | WRITE, &bv, 1, PAGE_SIZE); 297 + iov_iter_bvec(&from, WRITE, &bv, 1, PAGE_SIZE); 298 298 init_sync_kiocb(&kiocb, swap_file); 299 299 kiocb.ki_pos = page_file_offset(page); 300 300
+1 -1
net/9p/client.c
··· 2066 2066 struct kvec kv = {.iov_base = data, .iov_len = count}; 2067 2067 struct iov_iter to; 2068 2068 2069 - iov_iter_kvec(&to, READ | ITER_KVEC, &kv, 1, count); 2069 + iov_iter_kvec(&to, READ, &kv, 1, count); 2070 2070 2071 2071 p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n", 2072 2072 fid->fid, (unsigned long long) offset, count);
+1 -1
net/9p/trans_virtio.c
··· 329 329 if (!iov_iter_count(data)) 330 330 return 0; 331 331 332 - if (!(data->type & ITER_KVEC)) { 332 + if (iov_iter_is_kvec(data)) { 333 333 int n; 334 334 /* 335 335 * We allow only p9_max_pages pinned. We wait for the
+1 -1
net/bluetooth/6lowpan.c
··· 467 467 iv.iov_len = skb->len; 468 468 469 469 memset(&msg, 0, sizeof(msg)); 470 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iv, 1, skb->len); 470 + iov_iter_kvec(&msg.msg_iter, WRITE, &iv, 1, skb->len); 471 471 472 472 err = l2cap_chan_send(chan, &msg, skb->len); 473 473 if (err > 0) {
+1 -1
net/bluetooth/a2mp.c
··· 63 63 64 64 memset(&msg, 0, sizeof(msg)); 65 65 66 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iv, 1, total_len); 66 + iov_iter_kvec(&msg.msg_iter, WRITE, &iv, 1, total_len); 67 67 68 68 l2cap_chan_send(chan, &msg, total_len); 69 69
+1 -1
net/bluetooth/smp.c
··· 622 622 623 623 memset(&msg, 0, sizeof(msg)); 624 624 625 - iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, iv, 2, 1 + len); 625 + iov_iter_kvec(&msg.msg_iter, WRITE, iv, 2, 1 + len); 626 626 627 627 l2cap_chan_send(chan, &msg, 1 + len); 628 628
+3 -3
net/ceph/messenger.c
··· 513 513 if (!buf) 514 514 msg.msg_flags |= MSG_TRUNC; 515 515 516 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, len); 516 + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, len); 517 517 r = sock_recvmsg(sock, &msg, msg.msg_flags); 518 518 if (r == -EAGAIN) 519 519 r = 0; ··· 532 532 int r; 533 533 534 534 BUG_ON(page_offset + length > PAGE_SIZE); 535 - iov_iter_bvec(&msg.msg_iter, READ | ITER_BVEC, &bvec, 1, length); 535 + iov_iter_bvec(&msg.msg_iter, READ, &bvec, 1, length); 536 536 r = sock_recvmsg(sock, &msg, msg.msg_flags); 537 537 if (r == -EAGAIN) 538 538 r = 0; ··· 594 594 else 595 595 msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */ 596 596 597 - iov_iter_bvec(&msg.msg_iter, WRITE | ITER_BVEC, &bvec, 1, size); 597 + iov_iter_bvec(&msg.msg_iter, WRITE, &bvec, 1, size); 598 598 ret = sock_sendmsg(sock, &msg); 599 599 if (ret == -EAGAIN) 600 600 ret = 0;
+1 -1
net/netfilter/ipvs/ip_vs_sync.c
··· 1616 1616 EnterFunction(7); 1617 1617 1618 1618 /* Receive a packet */ 1619 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, buflen); 1619 + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, buflen); 1620 1620 len = sock_recvmsg(sock, &msg, MSG_DONTWAIT); 1621 1621 if (len < 0) 1622 1622 return len;
+2 -2
net/smc/smc_clc.c
··· 286 286 */ 287 287 krflags = MSG_PEEK | MSG_WAITALL; 288 288 smc->clcsock->sk->sk_rcvtimeo = CLC_WAIT_TIME; 289 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, 289 + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, 290 290 sizeof(struct smc_clc_msg_hdr)); 291 291 len = sock_recvmsg(smc->clcsock, &msg, krflags); 292 292 if (signal_pending(current)) { ··· 325 325 326 326 /* receive the complete CLC message */ 327 327 memset(&msg, 0, sizeof(struct msghdr)); 328 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, datlen); 328 + iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, datlen); 329 329 krflags = MSG_WAITALL; 330 330 len = sock_recvmsg(smc->clcsock, &msg, krflags); 331 331 if (len < datlen || !smc_clc_msg_hdr_valid(clcm)) {
+3 -3
net/socket.c
··· 635 635 int kernel_sendmsg(struct socket *sock, struct msghdr *msg, 636 636 struct kvec *vec, size_t num, size_t size) 637 637 { 638 - iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size); 638 + iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size); 639 639 return sock_sendmsg(sock, msg); 640 640 } 641 641 EXPORT_SYMBOL(kernel_sendmsg); ··· 648 648 if (!sock->ops->sendmsg_locked) 649 649 return sock_no_sendmsg_locked(sk, msg, size); 650 650 651 - iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size); 651 + iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size); 652 652 653 653 return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); 654 654 } ··· 823 823 mm_segment_t oldfs = get_fs(); 824 824 int result; 825 825 826 - iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size); 826 + iov_iter_kvec(&msg->msg_iter, READ, vec, num, size); 827 827 set_fs(KERNEL_DS); 828 828 result = sock_recvmsg(sock, msg, flags); 829 829 set_fs(oldfs);
+1 -1
net/sunrpc/svcsock.c
··· 336 336 rqstp->rq_xprt_hlen = 0; 337 337 338 338 clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 339 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, nr, buflen); 339 + iov_iter_kvec(&msg.msg_iter, READ, iov, nr, buflen); 340 340 if (base != 0) { 341 341 iov_iter_advance(&msg.msg_iter, base); 342 342 buflen -= base;
+2 -2
net/sunrpc/xprtsock.c
··· 361 361 xs_read_kvec(struct socket *sock, struct msghdr *msg, int flags, 362 362 struct kvec *kvec, size_t count, size_t seek) 363 363 { 364 - iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, kvec, 1, count); 364 + iov_iter_kvec(&msg->msg_iter, READ, kvec, 1, count); 365 365 return xs_sock_recvmsg(sock, msg, flags, seek); 366 366 } 367 367 ··· 370 370 struct bio_vec *bvec, unsigned long nr, size_t count, 371 371 size_t seek) 372 372 { 373 - iov_iter_bvec(&msg->msg_iter, READ | ITER_BVEC, bvec, nr, count); 373 + iov_iter_bvec(&msg->msg_iter, READ, bvec, nr, count); 374 374 return xs_sock_recvmsg(sock, msg, flags, seek); 375 375 } 376 376
+1 -1
net/tipc/topsrv.c
··· 394 394 iov.iov_base = &s; 395 395 iov.iov_len = sizeof(s); 396 396 msg.msg_name = NULL; 397 - iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, iov.iov_len); 397 + iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, iov.iov_len); 398 398 ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT); 399 399 if (ret == -EWOULDBLOCK) 400 400 return -EWOULDBLOCK;
+2 -2
net/tls/tls_device.c
··· 489 489 490 490 iov.iov_base = kaddr + offset; 491 491 iov.iov_len = size; 492 - iov_iter_kvec(&msg_iter, WRITE | ITER_KVEC, &iov, 1, size); 492 + iov_iter_kvec(&msg_iter, WRITE, &iov, 1, size); 493 493 rc = tls_push_data(sk, &msg_iter, size, 494 494 flags, TLS_RECORD_TYPE_DATA); 495 495 kunmap(page); ··· 538 538 { 539 539 struct iov_iter msg_iter; 540 540 541 - iov_iter_kvec(&msg_iter, WRITE | ITER_KVEC, NULL, 0, 0); 541 + iov_iter_kvec(&msg_iter, WRITE, NULL, 0, 0); 542 542 return tls_push_data(sk, &msg_iter, 0, flags, TLS_RECORD_TYPE_DATA); 543 543 } 544 544
+2 -2
net/tls/tls_sw.c
··· 799 799 struct crypto_tfm *tfm = crypto_aead_tfm(ctx->aead_send); 800 800 bool async_capable = tfm->__crt_alg->cra_flags & CRYPTO_ALG_ASYNC; 801 801 unsigned char record_type = TLS_RECORD_TYPE_DATA; 802 - bool is_kvec = msg->msg_iter.type & ITER_KVEC; 802 + bool is_kvec = iov_iter_is_kvec(&msg->msg_iter); 803 803 bool eor = !(msg->msg_flags & MSG_MORE); 804 804 size_t try_to_copy, copied = 0; 805 805 struct sk_msg *msg_pl, *msg_en; ··· 1457 1457 bool cmsg = false; 1458 1458 int target, err = 0; 1459 1459 long timeo; 1460 - bool is_kvec = msg->msg_iter.type & ITER_KVEC; 1460 + bool is_kvec = iov_iter_is_kvec(&msg->msg_iter); 1461 1461 int num_async = 0; 1462 1462 1463 1463 flags |= nonblock;