Linux 4.13: use designated initializers where required
[openafs.git] / src / afs / LINUX / osi_misc.c
index 140cee4..077d4ed 100644 (file)
 
 
 #include <linux/module.h> /* early to avoid printf->printk mapping */
-#if defined(AFS_LINUX26_ENV)
-#include "h/dcache.h"
-#include "h/namei.h"
-#include "h/kthread.h"
-#endif
+#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
+
+#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
@@ -73,7 +49,6 @@ osi_linux_mask(void)
     SIG_UNLOCK(current);
 }
 
-#if defined(AFS_LINUX24_ENV)
 /* LOOKUP_POSITIVE is becoming the default */
 #ifndef LOOKUP_POSITIVE
 #define LOOKUP_POSITIVE 0
@@ -84,102 +59,88 @@ osi_lookupname_internal(char *aname, int followlink, struct vfsmount **mnt,
                        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;
-    }
-    code = osi_lookupname_internal(tname, followlink, NULL, dpp);   
-    if (seg == AFS_UIOUSER) {
-        putname(tname);
+    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;
     }
-    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);
@@ -195,7 +156,7 @@ int osi_abspath(char *aname, char *buf, int buflen,
        mntput(mnt);
     }
 
-    putname(tname);
+    afs_putname(name);
     return code;
 }
 
@@ -216,4 +177,3 @@ void afs_start_thread(void (*proc)(void), char *name)
 {
     kthread_run(afs_thread_wrapper, proc, "%s", name);
 }
-#endif