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