super.c (c9d35ee049b40f1d73e890bf88dd55f83b1e9be8) | super.c (b27a939e8376a3f1ed09b9c33ef44d20f18ec3d0) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2 3#include <linux/ceph/ceph_debug.h> 4 5#include <linux/backing-dev.h> 6#include <linux/ctype.h> 7#include <linux/fs.h> 8#include <linux/inet.h> --- 189 unchanged lines hidden (view full) --- 198}; 199 200struct ceph_parse_opts_ctx { 201 struct ceph_options *copts; 202 struct ceph_mount_options *opts; 203}; 204 205/* | 1// SPDX-License-Identifier: GPL-2.0-only 2 3#include <linux/ceph/ceph_debug.h> 4 5#include <linux/backing-dev.h> 6#include <linux/ctype.h> 7#include <linux/fs.h> 8#include <linux/inet.h> --- 189 unchanged lines hidden (view full) --- 198}; 199 200struct ceph_parse_opts_ctx { 201 struct ceph_options *copts; 202 struct ceph_mount_options *opts; 203}; 204 205/* |
206 * Remove adjacent slashes and then the trailing slash, unless it is 207 * the only remaining character. 208 * 209 * E.g. "//dir1////dir2///" --> "/dir1/dir2", "///" --> "/". 210 */ 211static void canonicalize_path(char *path) 212{ 213 int i, j = 0; 214 215 for (i = 0; path[i] != '\0'; i++) { 216 if (path[i] != '/' || j < 1 || path[j - 1] != '/') 217 path[j++] = path[i]; 218 } 219 220 if (j > 1 && path[j - 1] == '/') 221 j--; 222 path[j] = '\0'; 223} 224 225/* |
|
206 * Parse the source parameter. Distinguish the server list from the path. 207 * 208 * The source will look like: 209 * <server_spec>[,<server_spec>...]:[<path>] 210 * where 211 * <server_spec> is <ip>[:<port>] 212 * <path> is optional, but if present must begin with '/' 213 */ --- 5 unchanged lines hidden (view full) --- 219 int ret; 220 221 dout("%s '%s'\n", __func__, dev_name); 222 if (!dev_name || !*dev_name) 223 return invalfc(fc, "Empty source"); 224 225 dev_name_end = strchr(dev_name, '/'); 226 if (dev_name_end) { | 226 * Parse the source parameter. Distinguish the server list from the path. 227 * 228 * The source will look like: 229 * <server_spec>[,<server_spec>...]:[<path>] 230 * where 231 * <server_spec> is <ip>[:<port>] 232 * <path> is optional, but if present must begin with '/' 233 */ --- 5 unchanged lines hidden (view full) --- 239 int ret; 240 241 dout("%s '%s'\n", __func__, dev_name); 242 if (!dev_name || !*dev_name) 243 return invalfc(fc, "Empty source"); 244 245 dev_name_end = strchr(dev_name, '/'); 246 if (dev_name_end) { |
227 kfree(fsopt->server_path); 228 | |
229 /* 230 * The server_path will include the whole chars from userland 231 * including the leading '/'. 232 */ | 247 /* 248 * The server_path will include the whole chars from userland 249 * including the leading '/'. 250 */ |
251 kfree(fsopt->server_path); |
|
233 fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); 234 if (!fsopt->server_path) 235 return -ENOMEM; | 252 fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL); 253 if (!fsopt->server_path) 254 return -ENOMEM; |
255 256 canonicalize_path(fsopt->server_path); |
|
236 } else { 237 dev_name_end = dev_name + strlen(dev_name); 238 } 239 240 dev_name_end--; /* back up to ':' separator */ 241 if (dev_name_end < dev_name || *dev_name_end != ':') 242 return invalfc(fc, "No path or : separator in source"); 243 --- 207 unchanged lines hidden (view full) --- 451 return 0; 452 if (s1 && !s2) 453 return -1; 454 if (!s1 && s2) 455 return 1; 456 return strcmp(s1, s2); 457} 458 | 257 } else { 258 dev_name_end = dev_name + strlen(dev_name); 259 } 260 261 dev_name_end--; /* back up to ':' separator */ 262 if (dev_name_end < dev_name || *dev_name_end != ':') 263 return invalfc(fc, "No path or : separator in source"); 264 --- 207 unchanged lines hidden (view full) --- 472 return 0; 473 if (s1 && !s2) 474 return -1; 475 if (!s1 && s2) 476 return 1; 477 return strcmp(s1, s2); 478} 479 |
459/** 460 * path_remove_extra_slash - Remove the extra slashes in the server path 461 * @server_path: the server path and could be NULL 462 * 463 * Return NULL if the path is NULL or only consists of "/", or a string 464 * without any extra slashes including the leading slash(es) and the 465 * slash(es) at the end of the server path, such as: 466 * "//dir1////dir2///" --> "dir1/dir2" 467 */ 468static char *path_remove_extra_slash(const char *server_path) 469{ 470 const char *path = server_path; 471 const char *cur, *end; 472 char *buf, *p; 473 int len; 474 475 /* if the server path is omitted */ 476 if (!path) 477 return NULL; 478 479 /* remove all the leading slashes */ 480 while (*path == '/') 481 path++; 482 483 /* if the server path only consists of slashes */ 484 if (*path == '\0') 485 return NULL; 486 487 len = strlen(path); 488 489 buf = kmalloc(len + 1, GFP_KERNEL); 490 if (!buf) 491 return ERR_PTR(-ENOMEM); 492 493 end = path + len; 494 p = buf; 495 do { 496 cur = strchr(path, '/'); 497 if (!cur) 498 cur = end; 499 500 len = cur - path; 501 502 /* including one '/' */ 503 if (cur != end) 504 len += 1; 505 506 memcpy(p, path, len); 507 p += len; 508 509 while (cur <= end && *cur == '/') 510 cur++; 511 path = cur; 512 } while (path < end); 513 514 *p = '\0'; 515 516 /* 517 * remove the last slash if there has and just to make sure that 518 * we will get something like "dir1/dir2" 519 */ 520 if (*(--p) == '/') 521 *p = '\0'; 522 523 return buf; 524} 525 | |
526static int compare_mount_options(struct ceph_mount_options *new_fsopt, 527 struct ceph_options *new_opt, 528 struct ceph_fs_client *fsc) 529{ 530 struct ceph_mount_options *fsopt1 = new_fsopt; 531 struct ceph_mount_options *fsopt2 = fsc->mount_options; 532 int ofs = offsetof(struct ceph_mount_options, snapdir_name); | 480static int compare_mount_options(struct ceph_mount_options *new_fsopt, 481 struct ceph_options *new_opt, 482 struct ceph_fs_client *fsc) 483{ 484 struct ceph_mount_options *fsopt1 = new_fsopt; 485 struct ceph_mount_options *fsopt2 = fsc->mount_options; 486 int ofs = offsetof(struct ceph_mount_options, snapdir_name); |
533 char *p1, *p2; | |
534 int ret; 535 536 ret = memcmp(fsopt1, fsopt2, ofs); 537 if (ret) 538 return ret; 539 540 ret = strcmp_null(fsopt1->snapdir_name, fsopt2->snapdir_name); 541 if (ret) 542 return ret; | 487 int ret; 488 489 ret = memcmp(fsopt1, fsopt2, ofs); 490 if (ret) 491 return ret; 492 493 ret = strcmp_null(fsopt1->snapdir_name, fsopt2->snapdir_name); 494 if (ret) 495 return ret; |
496 |
|
543 ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace); 544 if (ret) 545 return ret; 546 | 497 ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace); 498 if (ret) 499 return ret; 500 |
547 p1 = path_remove_extra_slash(fsopt1->server_path); 548 if (IS_ERR(p1)) 549 return PTR_ERR(p1); 550 p2 = path_remove_extra_slash(fsopt2->server_path); 551 if (IS_ERR(p2)) { 552 kfree(p1); 553 return PTR_ERR(p2); 554 } 555 ret = strcmp_null(p1, p2); 556 kfree(p1); 557 kfree(p2); | 501 ret = strcmp_null(fsopt1->server_path, fsopt2->server_path); |
558 if (ret) 559 return ret; 560 561 ret = strcmp_null(fsopt1->fscache_uniq, fsopt2->fscache_uniq); 562 if (ret) 563 return ret; 564 565 return ceph_compare_options(new_opt, fsc->client); --- 386 unchanged lines hidden (view full) --- 952 int err; 953 unsigned long started = jiffies; /* note the start time */ 954 struct dentry *root; 955 956 dout("mount start %p\n", fsc); 957 mutex_lock(&fsc->client->mount_mutex); 958 959 if (!fsc->sb->s_root) { | 502 if (ret) 503 return ret; 504 505 ret = strcmp_null(fsopt1->fscache_uniq, fsopt2->fscache_uniq); 506 if (ret) 507 return ret; 508 509 return ceph_compare_options(new_opt, fsc->client); --- 386 unchanged lines hidden (view full) --- 896 int err; 897 unsigned long started = jiffies; /* note the start time */ 898 struct dentry *root; 899 900 dout("mount start %p\n", fsc); 901 mutex_lock(&fsc->client->mount_mutex); 902 903 if (!fsc->sb->s_root) { |
960 const char *path, *p; | 904 const char *path = fsc->mount_options->server_path ? 905 fsc->mount_options->server_path + 1 : ""; 906 |
961 err = __ceph_open_session(fsc->client, started); 962 if (err < 0) 963 goto out; 964 965 /* setup fscache */ 966 if (fsc->mount_options->flags & CEPH_MOUNT_OPT_FSCACHE) { 967 err = ceph_fscache_register_fs(fsc, fc); 968 if (err < 0) 969 goto out; 970 } 971 | 907 err = __ceph_open_session(fsc->client, started); 908 if (err < 0) 909 goto out; 910 911 /* setup fscache */ 912 if (fsc->mount_options->flags & CEPH_MOUNT_OPT_FSCACHE) { 913 err = ceph_fscache_register_fs(fsc, fc); 914 if (err < 0) 915 goto out; 916 } 917 |
972 p = path_remove_extra_slash(fsc->mount_options->server_path); 973 if (IS_ERR(p)) { 974 err = PTR_ERR(p); 975 goto out; 976 } 977 /* if the server path is omitted or just consists of '/' */ 978 if (!p) 979 path = ""; 980 else 981 path = p; | |
982 dout("mount opening path '%s'\n", path); 983 984 ceph_fs_debugfs_init(fsc); 985 986 root = open_root_dentry(fsc, path, started); | 918 dout("mount opening path '%s'\n", path); 919 920 ceph_fs_debugfs_init(fsc); 921 922 root = open_root_dentry(fsc, path, started); |
987 kfree(p); | |
988 if (IS_ERR(root)) { 989 err = PTR_ERR(root); 990 goto out; 991 } 992 fsc->sb->s_root = dget(root); 993 } else { 994 root = dget(fsc->sb->s_root); 995 } --- 334 unchanged lines hidden --- | 923 if (IS_ERR(root)) { 924 err = PTR_ERR(root); 925 goto out; 926 } 927 fsc->sb->s_root = dget(root); 928 } else { 929 root = dget(fsc->sb->s_root); 930 } --- 334 unchanged lines hidden --- |