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.
190 lines
5.0 KiB
190 lines
5.0 KiB
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;
|
|
|