static ssize_t write_ports(struct file *file, char *buf, size_t size) { if (size == 0) { int len = 0; lock_kernel(); if (nfsd_serv) len = svc_sock_names(buf, nfsd_serv, NULL); unlock_kernel(); return len; } /* Either a single 'fd' number is written, in which * case it must be for a socket of a supported family/protocol, * and we use it as an nfsd socket, or * A '-' followed by the 'name' of a socket in which case * we close the socket. */ if (isdigit(buf[0])) { char *mesg = buf; int fd; int err; err = get_int(&mesg, &fd); if (err) return -EINVAL; if (fd < 0) return -EINVAL; err = nfsd_create_serv(); if (!err) { int proto = 0; err = svc_addsock(nfsd_serv, fd, buf, &proto); if (err >= 0) { err = lockd_up(proto); if (err < 0) svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf); } /* Decrease the count, but don't shutdown the * the service */ lock_kernel(); nfsd_serv->sv_nrthreads--; unlock_kernel(); } return err < 0 ? err : 0; } if (buf[0] == '-') { char *toclose = kstrdup(buf+1, GFP_KERNEL); int len = 0; if (!toclose) return -ENOMEM; lock_kernel(); if (nfsd_serv) len = svc_sock_names(buf, nfsd_serv, toclose); unlock_kernel(); if (len >= 0) lockd_down(); kfree(toclose); return len; } return -EINVAL; }
/* * A '-' followed by the 'name' of a socket means we close the socket. */ static ssize_t __write_ports_delfd(char *buf) { char *toclose; int len = 0; toclose = kstrdup(buf + 1, GFP_KERNEL); if (toclose == NULL) return -ENOMEM; if (nfsd_serv != NULL) len = svc_sock_names(nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT, toclose); kfree(toclose); return len; }