From: Jeff Mahoney <jeffm@suse.com>
To: Ian Kent <raven@themaw.net>, autofs@vger.kernel.org
Subject: Re: [PATCH] autofs: improve scalability of direct mount path component creation
Date: Tue, 22 Mar 2016 10:38:37 -0400 [thread overview]
Message-ID: <56F158ED.5070001@suse.com> (raw)
In-Reply-To: <56F152FA.1000205@suse.com>
[-- Attachment #1.1: Type: text/plain, Size: 5930 bytes --]
On 3/22/16 10:13 AM, Jeff Mahoney wrote:
> 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.
I did test this in the expected scenarios:
- With an NFS (ch)root, direct mount on NFS root, created.
- With an NFS (ch)root, direct mount on NFS mount, did not create.
- With a local root, direct mount on root fs, created.
- With a local root, direct mount on another local fs, created.
- With a local root, direct mount on NFS, did not create.
-Jeff
> Signed-off-by: Jeff Mahoney <jeffm@suse.com>
> ---
> daemon/automount.c | 56 +++++++++++++++++++++++++++++++++++++++--------------
> include/automount.h | 2 ++
> include/mounts.h | 1 -
> lib/mounts.c | 45 ------------------------------------------
> 4 files changed, 44 insertions(+), 60 deletions(-)
>
> diff --git a/daemon/automount.c b/daemon/automount.c
> index 74e62a1..9d07425 100644
> --- a/daemon/automount.c
> +++ b/daemon/automount.c
> @@ -98,10 +98,25 @@ static int umount_all(struct autofs_point *ap, int force);
>
> extern struct master *master_list;
>
> +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 */
> @@ -114,24 +129,37 @@ static int do_mkdir(const char *parent, const char *path, mode_t mode)
> }
>
> /*
> - * 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;
> }
> diff --git a/include/automount.h b/include/automount.h
> index 2cf0611..c0f5fbf 100644
> --- a/include/automount.h
> +++ b/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
>
> /* This sould be enough for at least 20 host aliases */
> #define HOST_ENT_BUF_SIZE 2048
> diff --git a/include/mounts.h b/include/mounts.h
> index cce646a..489025c 100644
> --- a/include/mounts.h
> +++ b/include/mounts.h
> @@ -101,7 +101,6 @@ int ext_mount_remove(struct list_head *, const char *);
> 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);
> diff --git a/lib/mounts.c b/lib/mounts.c
> index 455bdca..1d1b4da 100644
> --- a/lib/mounts.c
> +++ b/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;
>
--
Jeff Mahoney
SUSE Labs
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 881 bytes --]
next prev parent reply other threads:[~2016-03-22 14:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-18 20:44 [BUG] contained_in_local_fs will *always* return true Jeff Mahoney
2016-03-18 21:25 ` [PATCH] autofs: fix contained_in_local_fs and improve scalability Jeff Mahoney
2016-03-19 20:58 ` Jeff Mahoney
2016-03-21 3:44 ` Ian Kent
2016-03-21 22:08 ` Jeff Mahoney
2016-03-22 0:24 ` Ian Kent
2016-03-22 3:50 ` Jeff Mahoney
2016-03-22 14:13 ` [PATCH] autofs: improve scalability of direct mount path component creation Jeff Mahoney
2016-03-22 14:38 ` Jeff Mahoney [this message]
2016-03-24 1:23 ` Ian Kent
2016-03-22 1:24 ` [PATCH] autofs: fix contained_in_local_fs and improve scalability Marion, Mike
2016-03-20 13:05 ` [BUG] contained_in_local_fs will *always* return true Ian Kent
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56F158ED.5070001@suse.com \
--to=jeffm@suse.com \
--cc=autofs@vger.kernel.org \
--cc=raven@themaw.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox