+static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
+{
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ };
+ int b1, b2, b3, b4;
+ char c;
+ char *fo_path;
+
+ /* sanity check */
+ if (size == 0)
+ return -EINVAL;
+
+ if (buf[size-1] != '\n')
+ return -EINVAL;
+
+ fo_path = buf;
+ if (qword_get(&buf, fo_path, size) < 0)
+ return -EINVAL;
+
+ /* get ipv4 address */
+ if (sscanf(fo_path, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) != 4)
+ return -EINVAL;
+ if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255)
+ return -EINVAL;
+ sin.sin_addr.s_addr = htonl((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
+
+ return nlmsvc_unlock_all_by_ip((struct sockaddr *)&sin);
+}
+
+static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
+{
+ struct nameidata nd;
+ char *fo_path;
+ int error;
+
+ /* sanity check */
+ if (size == 0)
+ return -EINVAL;
+
+ if (buf[size-1] != '\n')
+ return -EINVAL;
+
+ fo_path = buf;
+ if (qword_get(&buf, fo_path, size) < 0)
+ return -EINVAL;
+
+ error = path_lookup(fo_path, 0, &nd);
+ if (error)
+ return error;
+
+ error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
+
+ path_put(&nd.path);
+ return error;
+}
+