diff options
author | Dean Roehrich <roehrich@sgi.com> | 2002-06-18 21:05:48 +0000 |
---|---|---|
committer | Dean Roehrich <roehrich@sgi.com> | 2002-06-18 21:05:48 +0000 |
commit | 53868d92ca48e68b1572f20a1b6fa889bee06da4 (patch) | |
tree | daf19dd294ccaaf2b2f38c0667e0fb3defb8eb6c | |
parent | 7049620a744365b4147efef612daf9da437c1311 (diff) | |
download | dmapi-dev-53868d92ca48e68b1572f20a1b6fa889bee06da4.tar.gz |
In dm_handle_to_path(), use getmntent() to walk through the filesystems,
looking for one with an fshandle that matches that of the object we're trying
to find. Open that path so we have a filedescriptor, and hence a valid
vfsmount structure, to give to dm_open_by_handle(). This simplifies a mess on
the kernel side.
No Message Supplied
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | build/rpm/dmapi.spec.in | 2 | ||||
-rw-r--r-- | debian/control | 4 | ||||
-rw-r--r-- | doc/CHANGES | 3 | ||||
-rw-r--r-- | libdm/Makefile | 2 | ||||
-rw-r--r-- | libdm/dm_handle2path.c | 110 | ||||
-rw-r--r-- | libdm/dmapi_lib.c | 9 |
7 files changed, 96 insertions, 36 deletions
@@ -3,5 +3,5 @@ # PKG_MAJOR=2 PKG_MINOR=0 -PKG_REVISION=3 +PKG_REVISION=4 PKG_BUILD=0 diff --git a/build/rpm/dmapi.spec.in b/build/rpm/dmapi.spec.in index 7e77006..69abb4c 100644 --- a/build/rpm/dmapi.spec.in +++ b/build/rpm/dmapi.spec.in @@ -23,7 +23,7 @@ by the libdm library. %package devel Summary: Data Management API static libraries and headers. Group: Development/Libraries -Requires: @pkg_name@ >= 2.0.3 +Requires: @pkg_name@ >= 2.0.4 %description devel dmapi-devel contains the libraries and header files needed to diff --git a/debian/control b/debian/control index 5cf5f88..7a109b5 100644 --- a/debian/control +++ b/debian/control @@ -19,8 +19,8 @@ Description: Data Management API runtime environment Package: dmapi-dev Section: devel Priority: extra -Depends: libc6-dev, dmapi (>= 2.0.3), xfslibs-dev (>= 2.0.0) -Conflicts: dmapi (<< 2.0.3), xfslibs-dev (<< 2.0.0) +Depends: libc6-dev, dmapi (>= 2.0.4), xfslibs-dev (>= 2.0.0) +Conflicts: dmapi (<< 2.0.4), xfslibs-dev (<< 2.0.0) Architecture: any Description: Data Management API static libraries and headers dmapi-dev contains the libraries and header files needed to diff --git a/doc/CHANGES b/doc/CHANGES index 9288870..04a45fc 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,3 +1,6 @@ +dmapi-2.0.4 (18 June 2002) + - kernel<>library interface for DM_OPEN_BY_HANDLE changed + dmapi-2.0.3 (12 June 2002) - kernel-library interface has changed, now 64bit safe. diff --git a/libdm/Makefile b/libdm/Makefile index 46a1a4b..2e2aa60 100644 --- a/libdm/Makefile +++ b/libdm/Makefile @@ -35,7 +35,7 @@ include $(TOPDIR)/include/builddefs LTLIBRARY = libdm.la LT_CURRENT = 0 -LT_REVISION = 3 +LT_REVISION = 4 LT_AGE = 0 HFILES = dmapi_lib.h diff --git a/libdm/dm_handle2path.c b/libdm/dm_handle2path.c index d3b9c2e..f5e6e26 100644 --- a/libdm/dm_handle2path.c +++ b/libdm/dm_handle2path.c @@ -31,6 +31,7 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ +#include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> @@ -38,6 +39,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <mntent.h> #ifdef linux #include <linux/types.h> #include <unistd.h> @@ -53,28 +55,9 @@ #include "dmapi_lib.h" -/* Originally this routine called SGI_OPEN_BY_HANDLE on the target object, did - a fstat on it, then searched for the matching inode number in the directory - pointed to by dirhanp. There were a couple of problems with this. - 1. dm_handle_to_path is supposed to work for symlink target objects, but - didn't because SGI_OPEN_BY_HANDLE only works for files and directories. - 2. The wrong pathname was sometimes returned if dirhanp and targhanp pointed - to the same directory (a common request) because ".", ".." and/or various - subdirectories could all be mount points and therefore all have the same - inode number of 128. - 3. dm_handle_to_path wouldn't work if targhanp was a mount point because - routine getcomp() sees only the mounted-on directory, not the mount point. - - This rework of dm_handle_to_path fixes all these problems, but at a price, - because routine getcomp() must make one system call per directory entry. - Someday these two methods should be combined. If an SGI_OPEN_BY_HANDLE of - targhanp works and if both dirhanp and targhanp have the same dev_t, then - use the old method, otherwise use the current method. This will remove - the system call overhead in nearly all cases. -*/ - static int getcomp(int dirfd, void *targhanp, size_t targhlen, char *bufp, size_t buflen, size_t *rlenp); +static char *get_mnt(void *fshanp, size_t fshlen); extern int @@ -90,6 +73,10 @@ dm_handle_to_path( int dirfd = -1; /* fd for parent directory */ int origfd = -1; /* fd for current working directory */ int err; /* a place to save errno */ + int mfd; + char *mtpt = NULL; + void *fshanp; + size_t fshlen; if (buflen == 0) { errno = EINVAL; @@ -99,14 +86,31 @@ dm_handle_to_path( errno = EFAULT; return -1; } - if ((origfd = open(".", O_RDONLY)) < 0) + if (dm_handle_to_fshandle(dirhanp, dirhlen, &fshanp, &fshlen)) { + errno = EINVAL; + return -1; + } + if ((origfd = open(".", O_RDONLY)) < 0) { + dm_handle_free(fshanp, fshlen); return -1; /* leave errno set from open */ + } + + if ((mtpt = get_mnt(fshanp, fshlen)) == NULL) { + errno = EINVAL; + dm_handle_free(fshanp, fshlen); + close(origfd); + return -1; + } + + if((mfd = open(mtpt, O_RDONLY)) < 0) { + dm_handle_free(fshanp, fshlen); + close(origfd); + free(mtpt); + return -1; + } + + dirfd = dmi(DM_OPEN_BY_HANDLE, mfd, dirhanp, dirhlen, O_RDONLY); -#ifdef linux - dirfd = dmi(DM_OPEN_BY_HANDLE, dirhanp, dirhlen, O_RDONLY); -#else - dirfd = (int)syssgi(SGI_OPEN_BY_HANDLE, dirhanp, dirhlen, O_RDONLY); -#endif if (dirfd < 0) { err = errno; } else if (fchdir(dirfd)) { @@ -160,6 +164,9 @@ dm_handle_to_path( (void) fchdir(origfd); /* can't do anything about a failure */ } + dm_handle_free(fshanp, fshlen); + free(mtpt); + close(mfd); if (origfd >= 0) (void)close(origfd); if (dirfd >= 0) @@ -181,7 +188,7 @@ dm_handle_to_path( Returns zero if successful, an appropriate errno if not. */ -#define READDIRSZ 16384 /* 6.x kernels use 16k buffer */ +#define READDIRSZ 16384 static int getcomp( @@ -303,3 +310,52 @@ getcomp( *rlenp = totlen; /* success! */ return(0); } + + +static char * +get_mnt( + void *fshanp, + size_t fshlen) +{ + FILE *file; + struct mntent *mntent; + char *mtpt = NULL; + void *hanp; + size_t hlen; + + if ((file = setmntent("/etc/mtab", "r")) == NULL) + return NULL; + + while((mntent = getmntent(file)) != NULL) { + + /* skip anything that isn't xfs */ + if (strcmp("xfs", mntent->mnt_type) != 0) + continue; + + /* skip root dir */ + if (strcmp("/", mntent->mnt_dir) == 0) + continue; + + /* skip anything that isn't dmapi */ + if ((hasmntopt(mntent, "dmapi") == 0) && + (hasmntopt(mntent, "xdsm") == 0)) { + continue; + } + + /* skip anything that won't report a handle */ + if (dm_path_to_fshandle(mntent->mnt_dir, &hanp, &hlen)) + continue; + + /* is this a match? */ + if (dm_handle_cmp(fshanp, fshlen, hanp, hlen) == 0) { + /* yes */ + mtpt = strdup(mntent->mnt_dir); + } + dm_handle_free(hanp, hlen); + + if (mtpt) + break; + } + endmntent(file); + return mtpt; +} diff --git a/libdm/dmapi_lib.c b/libdm/dmapi_lib.c index b358628..18295a0 100644 --- a/libdm/dmapi_lib.c +++ b/libdm/dmapi_lib.c @@ -50,7 +50,7 @@ static int dmapi_fd = -1; int dmi_init_service( char *versionstr ) { - dmapi_fd = open( "/proc/fs/xfs_dmapi_v1", O_RDWR ); + dmapi_fd = open( "/proc/fs/xfs_dmapi_v2", O_RDWR ); if( dmapi_fd == -1 ) return -1; return 0; @@ -368,9 +368,10 @@ dmi( int opcode, ... ) break; /* dm_handle2path */ case DM_OPEN_BY_HANDLE: - DM_Parg(u,1) = Parg(void*); - DM_Uarg(u,2) = Uarg(size_t); - DM_Uarg(u,3) = Uarg(int); + DM_Uarg(u,1) = Uarg(unsigned int); + DM_Parg(u,2) = Parg(void*); + DM_Uarg(u,3) = Uarg(size_t); + DM_Uarg(u,4) = Uarg(int); break; /* dm_hole */ case DM_GET_ALLOCINFO: |