You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
5.0 KiB
191 lines
5.0 KiB
7 years ago
|
autofs-5.1.1 - improve scalability of direct mount path component
|
||
|
|
||
|
From: Jeff Mahoney <jeffm@suse.com>
|
||
|
|
||
|
With direct mounts, we want to avoid creating path components on
|
||
|
remote file systems unless that file system is the root file system.
|
||
|
|
||
|
The check boils down to allowing the mkdir if:
|
||
|
1/ If it's the root directory, or
|
||
|
2/ If it's not a remote file system, or
|
||
|
3/ If it's a remote file system that's the root file system
|
||
|
|
||
|
We can do that without parsing the mount table and can
|
||
|
improve startup time for all cases.
|
||
|
|
||
|
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
||
|
---
|
||
|
CHANGELOG | 1
|
||
|
daemon/automount.c | 56 +++++++++++++++++++++++++++++++++++++++-------------
|
||
|
include/automount.h | 2 +
|
||
|
include/mounts.h | 1
|
||
|
lib/mounts.c | 45 -----------------------------------------
|
||
|
5 files changed, 45 insertions(+), 60 deletions(-)
|
||
|
|
||
|
--- autofs-5.0.7.orig/CHANGELOG
|
||
|
+++ autofs-5.0.7/CHANGELOG
|
||
|
@@ -245,6 +245,7 @@
|
||
|
- use autofs_point to store expire timeout where possibe.
|
||
|
- fix possible NULL derefernce.
|
||
|
- fix work around sss startup delay.
|
||
|
+- improve scalability of direct mount path component.
|
||
|
|
||
|
25/07/2012 autofs-5.0.7
|
||
|
=======================
|
||
|
--- autofs-5.0.7.orig/daemon/automount.c
|
||
|
+++ autofs-5.0.7/daemon/automount.c
|
||
|
@@ -135,10 +135,25 @@ void set_thread_mount_request_log_id(str
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+static int is_remote_fstype(unsigned int fs_type)
|
||
|
+{
|
||
|
+ int ret = 0;
|
||
|
+ switch (fs_type) {
|
||
|
+ case SMB_SUPER_MAGIC:
|
||
|
+ case CIFS_MAGIC_NUMBER:
|
||
|
+ case NCP_SUPER_MAGIC:
|
||
|
+ case NFS_SUPER_MAGIC:
|
||
|
+ ret = 1;
|
||
|
+ break;
|
||
|
+ };
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static int do_mkdir(const char *parent, const char *path, mode_t mode)
|
||
|
{
|
||
|
int status;
|
||
|
- struct stat st;
|
||
|
+ mode_t mask;
|
||
|
+ struct stat st, root;
|
||
|
struct statfs fs;
|
||
|
|
||
|
/* If path exists we're done */
|
||
|
@@ -151,24 +166,37 @@ static int do_mkdir(const char *parent,
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * If we're trying to create a directory within an autofs fs
|
||
|
- * or the path is contained in a localy mounted fs go ahead.
|
||
|
+ * We don't want to create the path on a remote file system
|
||
|
+ * unless it's the root file system.
|
||
|
+ * An empty parent means it's the root directory and always ok.
|
||
|
*/
|
||
|
- status = -1;
|
||
|
- if (*parent)
|
||
|
+ if (*parent) {
|
||
|
status = statfs(parent, &fs);
|
||
|
- if ((status != -1 && fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) ||
|
||
|
- contained_in_local_fs(path)) {
|
||
|
- mode_t mask = umask(0022);
|
||
|
- int ret = mkdir(path, mode);
|
||
|
- (void) umask(mask);
|
||
|
- if (ret == -1) {
|
||
|
- errno = EACCES;
|
||
|
- return 0;
|
||
|
+ if (status == -1)
|
||
|
+ goto fail;
|
||
|
+
|
||
|
+ if (is_remote_fstype(fs.f_type)) {
|
||
|
+ status = stat(parent, &st);
|
||
|
+ if (status == -1)
|
||
|
+ goto fail;
|
||
|
+
|
||
|
+ status = stat("/", &root);
|
||
|
+ if (status == -1)
|
||
|
+ goto fail;
|
||
|
+
|
||
|
+ if (st.st_dev != root.st_dev)
|
||
|
+ goto fail;
|
||
|
}
|
||
|
- return 1;
|
||
|
}
|
||
|
|
||
|
+ mask = umask(0022);
|
||
|
+ status = mkdir(path, mode);
|
||
|
+ (void) umask(mask);
|
||
|
+ if (status == -1)
|
||
|
+ goto fail;
|
||
|
+
|
||
|
+ return 1;
|
||
|
+fail:
|
||
|
errno = EACCES;
|
||
|
return 0;
|
||
|
}
|
||
|
--- autofs-5.0.7.orig/include/automount.h
|
||
|
+++ autofs-5.0.7/include/automount.h
|
||
|
@@ -75,6 +75,8 @@ int load_autofs4_module(void);
|
||
|
#define AUTOFS_SUPER_MAGIC 0x00000187L
|
||
|
#define SMB_SUPER_MAGIC 0x0000517BL
|
||
|
#define CIFS_MAGIC_NUMBER 0xFF534D42L
|
||
|
+#define NCP_SUPER_MAGIC 0x0000564CL
|
||
|
+#define NFS_SUPER_MAGIC 0x00006969L
|
||
|
|
||
|
#define ATTEMPT_ID_SIZE 24
|
||
|
|
||
|
--- autofs-5.0.7.orig/include/mounts.h
|
||
|
+++ autofs-5.0.7/include/mounts.h
|
||
|
@@ -101,7 +101,6 @@ int ext_mount_remove(struct list_head *,
|
||
|
struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
|
||
|
struct mnt_list *reverse_mnt_list(struct mnt_list *list);
|
||
|
void free_mnt_list(struct mnt_list *list);
|
||
|
-int contained_in_local_fs(const char *path);
|
||
|
int is_mounted(const char *table, const char *path, unsigned int type);
|
||
|
int has_fstab_option(const char *opt);
|
||
|
void tree_free_mnt_tree(struct mnt_list *tree);
|
||
|
--- autofs-5.0.7.orig/lib/mounts.c
|
||
|
+++ autofs-5.0.7/lib/mounts.c
|
||
|
@@ -941,51 +941,6 @@ void free_mnt_list(struct mnt_list *list
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-int contained_in_local_fs(const char *path)
|
||
|
-{
|
||
|
- struct mnt_list *mnts, *this;
|
||
|
- size_t pathlen = strlen(path);
|
||
|
- int ret;
|
||
|
-
|
||
|
- if (!path || !pathlen || pathlen > PATH_MAX)
|
||
|
- return 0;
|
||
|
-
|
||
|
- mnts = get_mnt_list(_PATH_MOUNTED, "/", 1);
|
||
|
- if (!mnts)
|
||
|
- return 0;
|
||
|
-
|
||
|
- ret = 0;
|
||
|
-
|
||
|
- for (this = mnts; this != NULL; this = this->next) {
|
||
|
- size_t len = strlen(this->path);
|
||
|
-
|
||
|
- if (!strncmp(path, this->path, len)) {
|
||
|
- if (len > 1 && pathlen > len && path[len] != '/')
|
||
|
- continue;
|
||
|
- else if (len == 1 && this->path[0] == '/') {
|
||
|
- /*
|
||
|
- * always return true on rootfs, we don't
|
||
|
- * want to break diskless clients.
|
||
|
- */
|
||
|
- ret = 1;
|
||
|
- } else if (this->fs_name[0] == '/') {
|
||
|
- if (strlen(this->fs_name) > 1) {
|
||
|
- if (this->fs_name[1] != '/')
|
||
|
- ret = 1;
|
||
|
- } else
|
||
|
- ret = 1;
|
||
|
- } else if (!strncmp("LABEL=", this->fs_name, 6) ||
|
||
|
- !strncmp("UUID=", this->fs_name, 5))
|
||
|
- ret = 1;
|
||
|
- break;
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- free_mnt_list(mnts);
|
||
|
-
|
||
|
- return ret;
|
||
|
-}
|
||
|
-
|
||
|
static int table_is_mounted(const char *table, const char *path, unsigned int type)
|
||
|
{
|
||
|
struct mntent *mnt;
|