git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 08/12] fsmonitor: determine if filesystem is local or remote

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Oct 10, 2022, 10:04 UTC
Message-ID
<221010.86sfjwouqx.gmgdl@evledraar.gmail.com>
In-Reply-To
<5ecbb3082f16956d049cfa98662f8e3384a6aea2.1665326258.git.gitgitgadget@gmail.com>
On Sun, Oct 09 2022, Eric DeCosta via GitGitGadget wrote:
Show 52 quoted lines
> From: Eric DeCosta <edecosta@mathworks.com>
>
> Compare the given path to the mounted filesystems. Find the mount that is
> the longest prefix of the path (if any) and determine if that mount is on a
> local or remote filesystem.
>
> Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
> ---
>  compat/fsmonitor/fsm-path-utils-linux.c | 163 ++++++++++++++++++++++++
>  1 file changed, 163 insertions(+)
>  create mode 100644 compat/fsmonitor/fsm-path-utils-linux.c
>
> diff --git a/compat/fsmonitor/fsm-path-utils-linux.c b/compat/fsmonitor/fsm-path-utils-linux.c
> new file mode 100644
> index 00000000000..369692a788f
> --- /dev/null
> +++ b/compat/fsmonitor/fsm-path-utils-linux.c
> @@ -0,0 +1,163 @@
> +#include "fsmonitor.h"
> +#include "fsmonitor-path-utils.h"
> +#include <errno.h>
> +#include <mntent.h>
> +#include <sys/mount.h>
> +#include <sys/statvfs.h>
> +
> +/*
> + * https://github.com/coreutils/gnulib/blob/master/lib/mountlist.c
> + */
> +#ifndef ME_REMOTE
> +/* A file system is "remote" if its Fs_name contains a ':'
> +   or if (it is of type (smbfs or cifs) and its Fs_name starts with '//')
> +   or if it is of any other of the listed types
> +   or Fs_name is equal to "-hosts" (used by autofs to mount remote fs).
> +   "VM" file systems like prl_fs or vboxsf are not considered remote here. */
> +# define ME_REMOTE(Fs_name, Fs_type)            \
> +	(strchr (Fs_name, ':') != NULL              \
> +	 || ((Fs_name)[0] == '/'                    \
> +		 && (Fs_name)[1] == '/'                 \
> +		 && (strcmp (Fs_type, "smbfs") == 0     \
> +			 || strcmp (Fs_type, "smb3") == 0   \
> +			 || strcmp (Fs_type, "cifs") == 0)) \
> +	 || strcmp (Fs_type, "acfs") == 0           \
> +	 || strcmp (Fs_type, "afs") == 0            \
> +	 || strcmp (Fs_type, "coda") == 0           \
> +	 || strcmp (Fs_type, "auristorfs") == 0     \
> +	 || strcmp (Fs_type, "fhgfs") == 0          \
> +	 || strcmp (Fs_type, "gpfs") == 0           \
> +	 || strcmp (Fs_type, "ibrix") == 0          \
> +	 || strcmp (Fs_type, "ocfs2") == 0          \
> +	 || strcmp (Fs_type, "vxfs") == 0           \
> +	 || strcmp ("-hosts", Fs_name) == 0)
> +#endif

So, this is just copy/pasted GPLv3 code into our GPLv2-only codebase?: https://github.com/coreutils/gnulib/blob/cd1fdabe8b66c102124b6a5b0c97dded20246b46/lib/mountlist.c#L230-L247

Show 14 quoted lines
> +static struct mntent *find_mount(const char *path, const struct statvfs *fs)
> +{
> +	const char *const mounts = "/proc/mounts";
> +	const char *rp = real_pathdup(path, 1);
> +	struct mntent *ment = NULL;
> +	struct mntent *found = NULL;
> +	struct statvfs mntfs;
> +	FILE *fp;
> +	int dlen, plen, flen = 0;
> +
> +	fp = setmntent(mounts, "r");
> +	if (!fp) {
> +		error_errno(_("setmntent('%s') failed"), mounts);
> +		return NULL;

This code would probably be nicer if you returned int, and passed a pointer to a struct to populate as a paremeter. Then you could just "return error..." for this and the below cases.

Show 40 quoted lines
> +	}
> +
> +	plen = strlen(rp);
> +
> +	/* read all the mount information and compare to path */
> +	while ((ment = getmntent(fp)) != NULL) {
> +		if (statvfs(ment->mnt_dir, &mntfs)) {
> +			switch (errno) {
> +			case EPERM:
> +			case ESRCH:
> +			case EACCES:
> +				continue;
> +			default:
> +				error_errno(_("statvfs('%s') failed"), ment->mnt_dir);
> +				endmntent(fp);is 
> +				return NULL;
> +			}
> +		}
> +
> +		/* is mount on the same filesystem and is a prefix of the path */
> +		if ((fs->f_fsid == mntfs.f_fsid) &&
> +			!strncmp(ment->mnt_dir, rp, strlen(ment->mnt_dir))) {
> +			dlen = strlen(ment->mnt_dir);
> +			if (dlen > plen)
> +				continue;
> +			/*
> +			 * root is always a potential match; otherwise look for
> +			 * directory prefix
> +			 */
> +			if ((dlen == 1 && ment->mnt_dir[0] == '/') ||
> +				(dlen > flen && (!rp[dlen] || rp[dlen] == '/'))) {
> +				flen = dlen;
> +				/*
> +				 * https://man7.org/linux/man-pages/man3/getmntent.3.html
> +				 *
> +				 * The pointer points to a static area of memory which is
> +				 * overwritten by subsequent calls to getmntent().
> +				 */
> +				if (!found)
> +					CALLOC_ARRAY(found, 1);

It seems we never populate >1 of these, so don't you just want xmalloc(). Or actually...

Show 6 quoted lines
> +				free(found->mnt_dir);
> +				free(found->mnt_type);
> +				free(found->mnt_fsname);
> +				found->mnt_dir = xmemdupz(ment->mnt_dir, strlen(ment->mnt_dir));
> +				found->mnt_type = xmemdupz(ment->mnt_type, strlen(ment->mnt_type));
> +				found->mnt_fsname = xmemdupz(ment->mnt_fsname, strlen(ment->mnt_fsname));

Don't mix mem*() and str*(). In this case we need the string to be '\0' delimited, so use xstrndup().

And once we do that, we might wonder why we're explicitly finding the '\0', just to pass it to the xstrn*() function, when we can just do:

	found->mnt_dir = xstrdup(ment->mnt_dir);
	...
Which would AFAICT be equivalent to what you're doing here.
Show 11 quoted lines
> +			}
> +		}
> +	}
> +	endmntent(fp);
> +
> +	return found;
> +}
> +
> +int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
> +{
> +	struct mntent *ment;

...make this (or above) a "struct mntent ment", then pass &ment down, so we can fill that struct? Dunno...

Show 17 quoted lines
> +	struct statvfs fs;
> +
> +	if (statvfs(path, &fs))
> +		return error_errno(_("statvfs('%s') failed"), path);
> +
> +	ment = find_mount(path, &fs);
> +	if (!ment)
> +		return -1;
> +
> +	trace_printf_key(&trace_fsmonitor,
> +			 "statvfs('%s') [flags 0x%08lx] '%s' '%s'",
> +			 path, fs.f_flag, ment->mnt_type, ment->mnt_fsname);
> +
> +	if (ME_REMOTE(ment->mnt_fsname, ment->mnt_type))
> +		fs_info->is_remote = 1;
> +	else
> +		fs_info->is_remote = 0;
Shorter:
	fs_info->is_remote = ME_REMOTE(ment->mnt_fsname, ment->mnt_type);
Previous: Eric DeCosta via GitGitGadgetNext: Eric DeCosta
Message 13 of 89 in “fsmonitor: Implement fsmonitor for Linux”
  1. 00/12 fsmonitor: Implement fsmonitor for LinuxEric DeCosta via GitGitGadget, Oct 9, 2022
  2. 02/12 fsmonitor: relocate socket file if .git directory is remoteEric DeCosta via GitGitGadget, Oct 9, 2022
  3. 04/12 fsmonitor: deal with synthetic firmlinks on macOSEric DeCosta via GitGitGadget, Oct 9, 2022
  4. 03/12 fsmonitor: avoid socket location check if using hookEric DeCosta via GitGitGadget, Oct 9, 2022
  5. 05/12 fsmonitor: check for compatability before communicating with fsmonitorEric DeCosta via GitGitGadget, Oct 9, 2022
  6. 01/12 fsmonitor: refactor filesystem checks to common interfaceEric DeCosta via GitGitGadget, Oct 9, 2022
  7. Ævar Arnfjörð BjarmasonOct 18, 2022
  8. 06/12 fsmonitor: add documentation for allowRemote and socketDir optionsEric DeCosta via GitGitGadget, Oct 9, 2022
  9. 07/12 fsmonitor: prepare to share code between Mac OS and LinuxEric DeCosta via GitGitGadget, Oct 9, 2022
  10. Junio C HamanoOct 9, 2022
  11. Jeff HostetlerOct 10, 2022
  12. 08/12 fsmonitor: determine if filesystem is local or remoteEric DeCosta via GitGitGadget, Oct 9, 2022
  13. Ævar Arnfjörð BjarmasonOct 10, 2022
  14. Eric DeCostaOct 14, 2022
  15. 09/12 fsmonitor: implement filesystem change listener for LinuxEric DeCosta via GitGitGadget, Oct 9, 2022
  16. 10/12 fsmonitor: enable fsmonitor for LinuxEric DeCosta via GitGitGadget, Oct 9, 2022
  17. 11/12 fsmonitor: test updatesEric DeCosta via GitGitGadget, Oct 9, 2022
  18. Ævar Arnfjörð BjarmasonOct 18, 2022
  19. 12/12 fsmonitor: update doc for LinuxEric DeCosta via GitGitGadget, Oct 9, 2022
  20. Ævar Arnfjörð BjarmasonOct 18, 2022
  21. Junio C HamanoOct 9, 2022
  22. Eric SunshineOct 10, 2022
  23. Junio C HamanoOct 10, 2022
  24. 00/12 fsmonitor: Implement fsmonitor for LinuxEric DeCosta via GitGitGadget, Oct 14, 2022
  25. 01/12 fsmonitor: refactor filesystem checks to common interfaceEric DeCosta via GitGitGadget, Oct 14, 2022
  26. 02/12 fsmonitor: relocate socket file if .git directory is remoteEric DeCosta via GitGitGadget, Oct 14, 2022
  27. Ævar Arnfjörð BjarmasonOct 18, 2022
  28. 05/12 fsmonitor: check for compatability before communicating with fsmonitorEric DeCosta via GitGitGadget, Oct 14, 2022
  29. 03/12 fsmonitor: avoid socket location check if using hookEric DeCosta via GitGitGadget, Oct 14, 2022
  30. 04/12 fsmonitor: deal with synthetic firmlinks on macOSEric DeCosta via GitGitGadget, Oct 14, 2022
  31. 06/12 fsmonitor: add documentation for allowRemote and socketDir optionsEric DeCosta via GitGitGadget, Oct 14, 2022
  32. 07/12 fsmonitor: prepare to share code between Mac OS and LinuxEric DeCosta via GitGitGadget, Oct 14, 2022
  33. Junio C HamanoOct 14, 2022
  34. Eric DeCostaOct 17, 2022
  35. Junio C HamanoOct 18, 2022
  36. 10/12 fsmonitor: enable fsmonitor for LinuxEric DeCosta via GitGitGadget, Oct 14, 2022
  37. 11/12 fsmonitor: test updatesEric DeCosta via GitGitGadget, Oct 14, 2022
  38. 09/12 fsmonitor: implement filesystem change listener for LinuxEric DeCosta via GitGitGadget, Oct 14, 2022
  39. Ævar Arnfjörð BjarmasonOct 18, 2022
  40. 08/12 fsmonitor: determine if filesystem is local or remoteEric DeCosta via GitGitGadget, Oct 14, 2022
  41. 12/12 fsmonitor: update doc for LinuxEric DeCosta via GitGitGadget, Oct 14, 2022
  42. Junio C HamanoOct 14, 2022
  43. Eric DeCostaOct 17, 2022
  44. Junio C HamanoOct 17, 2022
  45. Johannes SchindelinOct 18, 2022
  46. Glen ChooOct 17, 2022
  47. Junio C HamanoOct 18, 2022
  48. Glen ChooOct 18, 2022
  49. Junio C HamanoOct 18, 2022
  50. Ævar Arnfjörð BjarmasonOct 19, 2022
  51. Eric SunshineOct 19, 2022
  52. Junio C HamanoOct 19, 2022
  53. Ævar Arnfjörð BjarmasonOct 19, 2022
  54. Eric SunshineOct 19, 2022
  55. Ævar Arnfjörð BjarmasonOct 19, 2022
  56. Junio C HamanoOct 19, 2022
  57. Junio C HamanoOct 20, 2022
  58. Eric SunshineOct 20, 2022
  59. Junio C HamanoOct 20, 2022
  60. Eric SunshineOct 20, 2022
  61. Junio C HamanoOct 20, 2022
  62. Junio C HamanoOct 20, 2022
  63. 0/6 fsmonitor: Implement fsmonitor for LinuxEric DeCosta via GitGitGadget, Nov 16, 2022
  64. 1/6 fsmonitor: prepare to share code between Mac OS and LinuxEric DeCosta via GitGitGadget, Nov 16, 2022
  65. 2/6 fsmonitor: determine if filesystem is local or remoteEric DeCosta via GitGitGadget, Nov 16, 2022
  66. 3/6 fsmonitor: implement filesystem change listener for LinuxEric DeCosta via GitGitGadget, Nov 16, 2022
  67. 4/6 fsmonitor: enable fsmonitor for LinuxEric DeCosta via GitGitGadget, Nov 16, 2022
  68. 5/6 fsmonitor: test updatesEric DeCosta via GitGitGadget, Nov 16, 2022
  69. 6/6 fsmonitor: update doc for LinuxEric DeCosta via GitGitGadget, Nov 16, 2022
  70. Taylor BlauNov 16, 2022
  71. 0/6 fsmonitor: Implement fsmonitor for LinuxEric DeCosta via GitGitGadget, Nov 23, 2022
  72. 1/6 fsmonitor: prepare to share code between Mac OS and LinuxEric DeCosta via GitGitGadget, Nov 23, 2022
  73. 2/6 fsmonitor: determine if filesystem is local or remoteEric DeCosta via GitGitGadget, Nov 23, 2022
  74. Junio C HamanoNov 25, 2022
  75. Ævar Arnfjörð BjarmasonDec 12, 2022
  76. 3/6 fsmonitor: implement filesystem change listener for LinuxEric DeCosta via GitGitGadget, Nov 23, 2022
  77. Ævar Arnfjörð BjarmasonDec 12, 2022
  78. 4/6 fsmonitor: enable fsmonitor for LinuxEric DeCosta via GitGitGadget, Nov 23, 2022
  79. 5/6 fsmonitor: test updatesEric DeCosta via GitGitGadget, Nov 23, 2022
  80. 6/6 fsmonitor: update doc for LinuxEric DeCosta via GitGitGadget, Nov 23, 2022
  81. 0/6 fsmonitor: Implement fsmonitor for LinuxEric DeCosta via GitGitGadget, Dec 12, 2022
  82. 1/6 fsmonitor: prepare to share code between Mac OS and LinuxEric DeCosta via GitGitGadget, Dec 12, 2022
  83. 2/6 fsmonitor: determine if filesystem is local or remoteEric DeCosta via GitGitGadget, Dec 12, 2022
  84. 4/6 fsmonitor: enable fsmonitor for LinuxEric DeCosta via GitGitGadget, Dec 12, 2022
  85. 3/6 fsmonitor: implement filesystem change listener for LinuxEric DeCosta via GitGitGadget, Dec 12, 2022
  86. 5/6 fsmonitor: test updatesEric DeCosta via GitGitGadget, Dec 12, 2022
  87. 6/6 fsmonitor: update doc for LinuxEric DeCosta via GitGitGadget, Dec 12, 2022
  88. Junio C HamanoApr 12, 2023
  89. Ævar Arnfjörð BjarmasonOct 18, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.