aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Roehrich <roehrich@sgi.com>2002-06-18 21:05:48 +0000
committerDean Roehrich <roehrich@sgi.com>2002-06-18 21:05:48 +0000
commit53868d92ca48e68b1572f20a1b6fa889bee06da4 (patch)
treedaf19dd294ccaaf2b2f38c0667e0fb3defb8eb6c
parent7049620a744365b4147efef612daf9da437c1311 (diff)
downloaddmapi-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--VERSION2
-rw-r--r--build/rpm/dmapi.spec.in2
-rw-r--r--debian/control4
-rw-r--r--doc/CHANGES3
-rw-r--r--libdm/Makefile2
-rw-r--r--libdm/dm_handle2path.c110
-rw-r--r--libdm/dmapi_lib.c9
7 files changed, 96 insertions, 36 deletions
diff --git a/VERSION b/VERSION
index a5c287c..d6fb318 100644
--- a/VERSION
+++ b/VERSION
@@ -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: