LINUX: Sometimes let dentry_open handle refcounts
[openafs.git] / src / afs / LINUX / osi_file.c
index 2602ec6..7389128 100644 (file)
@@ -15,7 +15,6 @@
 #include "afs/sysincludes.h"   /* Standard vendor system headers */
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs/afs_stats.h"     /* afs statistics */
-#include <linux/smp_lock.h>
 #include <linux/namei.h>
 
 #if defined(HAVE_LINUX_EXPORTFS_H)
@@ -50,21 +49,24 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
 
     dp = afs_get_dentry_from_fh(afs_cacheSBp, ainode, cache_fh_len, cache_fh_type,
                afs_fh_acceptable);
-    if (!dp)
+    if ((!dp) || IS_ERR(dp))
            osi_Panic("Can't get dentry\n");
     tip = dp->d_inode;
     tip->i_flags |= S_NOATIME; /* Disable updating access times. */
 
 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
     /* Use stashed credentials - prevent selinux/apparmor problems  */
-    filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, cache_creds);
+    filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, cache_creds);
     if (IS_ERR(filp))
-       filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, current_cred());
+       filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, current_cred());
 #else
-    filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR);
+    filp = dentry_open(dget(dp), mntget(afs_cacheMnt), O_RDWR);
 #endif
     if (IS_ERR(filp))
        osi_Panic("Can't open file: %d\n", (int) PTR_ERR(filp));
+
+    dput(dp);
+
     return filp;
 }
 
@@ -84,8 +86,8 @@ osi_UFSOpen(afs_dcache_id_t *ainode)
        crhold(&afs_osi_cred);  /* don't let it evaporate, since it is static */
        afs_osicred_initialized = 1;
     }
-    afile = (struct osi_file *)osi_AllocLargeSpace(sizeof(struct osi_file));
     AFS_GUNLOCK();
+    afile = kmalloc(sizeof(struct osi_file), GFP_NOFS);
     if (!afile) {
        osi_Panic("osi_UFSOpen: Failed to allocate %d bytes for osi_file.\n",
                  (int)sizeof(struct osi_file));
@@ -150,8 +152,7 @@ osi_UFSClose(struct osi_file *afile)
            filp_close(afile->filp, NULL);
        }
     }
-
-    osi_FreeLargeSpace(afile);
+    kfree(afile);
     return 0;
 }
 
@@ -217,7 +218,7 @@ afs_osi_Read(struct osi_file *afile, int offset, void *aptr,
        if (!afs_shuttingdown)
            osi_Panic("osi_Read called with null param");
        else
-           return EIO;
+           return -EIO;
     }
 
     if (offset != -1)
@@ -232,7 +233,9 @@ afs_osi_Read(struct osi_file *afile, int offset, void *aptr,
     } else {
        afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, auio.uio_resid,
                   ICL_TYPE_INT32, code);
-       code = -1;
+       if (code > 0) {
+           code = -code;
+       }
     }
     return code;
 }
@@ -252,7 +255,7 @@ afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
        if (!afs_shuttingdown)
            osi_Panic("afs_osi_Write called with null param");
        else
-           return EIO;
+           return -EIO;
     }
 
     if (offset != -1)
@@ -268,7 +271,9 @@ afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
        if (code == ENOSPC)
            afs_warnuser
                ("\n\n\n*** Cache partition is FULL - Decrease cachesize!!! ***\n\n");
-       code = -1;
+       if (code > 0) {
+           code = -code;
+       }
     }
 
     if (afile->proc)
@@ -334,7 +339,7 @@ osi_InitCacheInfo(char *aname)
  * kernel space.
  */
 int
-osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw)
+osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw)
 {
     struct file *filp = osifile->filp;
     mm_segment_t old_fs = {0};
@@ -402,7 +407,7 @@ osi_rdwr(struct osi_file *osifile, uio_t * uiop, int rw)
  * Setup a uio struct.
  */
 void
-setup_uio(uio_t * uiop, struct iovec *iovecp, const char *buf, afs_offs_t pos,
+setup_uio(struct uio *uiop, struct iovec *iovecp, const char *buf, afs_offs_t pos,
          int count, uio_flag_t flag, uio_seg_t seg)
 {
     iovecp->iov_base = (char *)buf;
@@ -421,7 +426,7 @@ setup_uio(uio_t * uiop, struct iovec *iovecp, const char *buf, afs_offs_t pos,
  * UIO_WRITE : uio -> dp
  */
 int
-uiomove(char *dp, int length, uio_flag_t rw, uio_t * uiop)
+uiomove(char *dp, int length, uio_flag_t rw, struct uio *uiop)
 {
     int count;
     struct iovec *iov;