#include <linux/module.h> /* early to avoid printf->printk mapping */
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/kthread.h>
#include "afs/sysincludes.h"
#include "afsincludes.h"
#include "afs/afs_stats.h"
-#if defined(AFS_LINUX24_ENV)
-#include "h/smp_lock.h"
-#endif
-#if defined(AFS_LINUX26_ENV)
-#include "h/namei.h"
-#include "h/kthread.h"
-#endif
+
+#include "osi_compat.h"
int afs_osicred_initialized = 0;
-struct AFS_UCRED afs_osi_cred;
+afs_ucred_t afs_osi_cred;
void
afs_osi_SetTime(osi_timeval_t * tvp)
{
-#if defined(AFS_LINUX24_ENV)
-
-#if defined(AFS_LINUX26_ENV)
struct timespec tv;
tv.tv_sec = tvp->tv_sec;
tv.tv_nsec = tvp->tv_usec * NSEC_PER_USEC;
-#else
- struct timeval tv;
- tv.tv_sec = tvp->tv_sec;
- tv.tv_usec = tvp->tv_usec;
-#endif
AFS_STATCNT(osi_SetTime);
do_settimeofday(&tv);
-#else
- extern int (*sys_settimeofdayp) (struct timeval * tv,
- struct timezone * tz);
-
- KERNEL_SPACE_DECL;
-
- AFS_STATCNT(osi_SetTime);
-
- TO_USER_SPACE();
- if (sys_settimeofdayp)
- (void)(*sys_settimeofdayp) (tvp, NULL);
- TO_KERNEL_SPACE();
-#endif
}
void
SIG_UNLOCK(current);
}
-#if defined(AFS_LINUX24_ENV)
/* LOOKUP_POSITIVE is becoming the default */
#ifndef LOOKUP_POSITIVE
#define LOOKUP_POSITIVE 0
struct dentry **dpp)
{
int code;
- struct nameidata nd;
+#if defined(HAVE_LINUX_PATH_LOOKUP)
+ struct nameidata path_data;
+#else
+ afs_linux_path_t path_data;
+#endif
int flags = LOOKUP_POSITIVE;
- code = ENOENT;
if (followlink)
flags |= LOOKUP_FOLLOW;
-#if defined(AFS_LINUX26_ENV)
- code = path_lookup(aname, flags, &nd);
-#else
- if (path_init(aname, flags, &nd))
- code = path_walk(aname, &nd);
-#endif
+ code = afs_kern_path(aname, flags, &path_data);
+
+ if (!code)
+ afs_get_dentry_ref(&path_data, mnt, dpp);
- if (!code) {
-#if defined(STRUCT_NAMEIDATA_HAS_PATH)
- *dpp = dget(nd.path.dentry);
- if (mnt)
- *mnt = mntget(nd.path.mnt);
- path_put(&nd.path);
-#else
- *dpp = dget(nd.dentry);
- if (mnt)
- *mnt = mntget(nd.mnt);
- path_release(&nd);
-#endif
- }
return code;
}
-int
-osi_lookupname(char *aname, uio_seg_t seg, int followlink,
- struct dentry **dpp)
+
+static char *
+afs_getname(char *aname)
{
- int code;
- char *tname;
- code = ENOENT;
- if (seg == AFS_UIOUSER) {
- tname = getname(aname);
- if (IS_ERR(tname))
- return PTR_ERR(tname);
- } else {
- tname = aname;
+ int len;
+ char *name = kmem_cache_alloc(names_cachep, GFP_KERNEL);
+
+ if (!name)
+ return ERR_PTR(-ENOMEM);
+
+ len = strncpy_from_user(name, aname, PATH_MAX);
+ if (len < 0)
+ goto error;
+ if (len >= PATH_MAX) {
+ len = -ENAMETOOLONG;
+ goto error;
}
- code = osi_lookupname_internal(tname, followlink, NULL, dpp);
- if (seg == AFS_UIOUSER) {
- putname(tname);
- }
- return code;
+ return name;
+
+error:
+ kmem_cache_free(names_cachep, name);
+ return ERR_PTR(len);
}
-#else
+
+static void
+afs_putname(char *name)
+{
+ kmem_cache_free(names_cachep, name);
+}
+
int
-osi_lookupname(char *aname, uio_seg_t seg, int followlink, struct dentry **dpp)
+osi_lookupname(char *aname, uio_seg_t seg, int followlink,
+ struct dentry **dpp)
{
- struct dentry *dp = NULL;
int code;
+ char *name;
- code = ENOENT;
if (seg == AFS_UIOUSER) {
- dp = followlink ? namei(aname) : lnamei(aname);
+ name = afs_getname(aname);
+ if (IS_ERR(name))
+ return -PTR_ERR(name);
} else {
- dp = lookup_dentry(aname, NULL, followlink ? 1 : 0);
+ name = aname;
}
-
- if (dp && !IS_ERR(dp)) {
- if (dp->d_inode) {
- *dpp = dp;
- code = 0;
- } else
- dput(dp);
+ code = osi_lookupname_internal(name, followlink, NULL, dpp);
+ if (seg == AFS_UIOUSER) {
+ afs_putname(name);
}
-
return code;
}
-#endif
-
-#ifdef AFS_LINUX26_ENV
-/* This is right even for Linux 2.4, but on that version d_path is inline
- * and implemented in terms of __d_path, which is not exported.
- */
int osi_abspath(char *aname, char *buf, int buflen,
int followlink, char **pathp)
{
struct dentry *dp = NULL;
struct vfsmount *mnt = NULL;
- char *tname, *path;
+ char *name, *path;
int code;
- code = ENOENT;
- tname = getname(aname);
- if (IS_ERR(tname))
- return -PTR_ERR(tname);
- code = osi_lookupname_internal(tname, followlink, &mnt, &dp);
+ name = afs_getname(aname);
+ if (IS_ERR(name))
+ return -PTR_ERR(name);
+ code = osi_lookupname_internal(name, followlink, &mnt, &dp);
if (!code) {
#if defined(D_PATH_TAKES_STRUCT_PATH)
- struct path p = { mnt, dp };
+ afs_linux_path_t p = { .mnt = mnt, .dentry = dp };
path = d_path(&p, buf, buflen);
#else
path = d_path(dp, mnt, buf, buflen);
mntput(mnt);
}
- putname(tname);
+ afs_putname(name);
return code;
}
{
kthread_run(afs_thread_wrapper, proc, "%s", name);
}
-#endif