LINUX: Sometimes let dentry_open handle refcounts
[openafs.git] / src / afs / LINUX / osi_file.c
index 13eb59d..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));
@@ -129,7 +131,7 @@ void osi_get_fh(struct dentry *dp, afs_ufs_dcache_id_t *ainode) {
 }
 
 int
-afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
+afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
 {
     AFS_STATCNT(osi_Stat);
     ObtainWriteLock(&afs_xosi, 320);
@@ -142,7 +144,7 @@ afs_osi_Stat(register struct osi_file *afile, register struct osi_stat *astat)
 }
 
 int
-osi_UFSClose(register struct osi_file *afile)
+osi_UFSClose(struct osi_file *afile)
 {
     AFS_STATCNT(osi_Close);
     if (afile) {
@@ -150,15 +152,14 @@ osi_UFSClose(register struct osi_file *afile)
            filp_close(afile->filp, NULL);
        }
     }
-
-    osi_FreeLargeSpace(afile);
+    kfree(afile);
     return 0;
 }
 
 int
-osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
+osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct osi_stat tstat;
     struct iattr newattrs;
     struct inode *inode = OSIFILE_INODE(afile);
@@ -183,16 +184,8 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
 
     /* avoid notify_change() since it wants to update dentry->d_parent */
     code = inode_change_ok(inode, &newattrs);
-    if (!code) {
-#ifdef INODE_SETATTR_NOT_VOID
-       if (inode->i_op && inode->i_op->setattr)
-           code = inode->i_op->setattr(afile->filp->f_dentry, &newattrs);
-       else
-           code = inode_setattr(inode, &newattrs);
-#else
-        inode_setattr(inode, &newattrs);
-#endif
-    }
+    if (!code)
+       code = afs_inode_setattr(afile, &newattrs);
     if (!code)
        truncate_inode_pages(&inode->i_data, asize);
     code = -code;
@@ -208,7 +201,7 @@ osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
 
 /* Generic read interface */
 int
-afs_osi_Read(register struct osi_file *afile, int offset, void *aptr,
+afs_osi_Read(struct osi_file *afile, int offset, void *aptr,
             afs_int32 asize)
 {
     struct uio auio;
@@ -225,7 +218,7 @@ afs_osi_Read(register 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)
@@ -240,14 +233,16 @@ afs_osi_Read(register 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;
 }
 
 /* Generic write interface */
 int
-afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr,
+afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
              afs_int32 asize)
 {
     struct uio auio;
@@ -260,7 +255,7 @@ afs_osi_Write(register 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)
@@ -276,7 +271,9 @@ afs_osi_Write(register 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)
@@ -290,7 +287,7 @@ afs_osi_Write(register struct osi_file *afile, afs_int32 offset, void *aptr,
     This routine written from the RT NFS port strategy routine.
     It has been generalized a bit, but should still be pretty clear. */
 int
-afs_osi_MapStrategy(int (*aproc) (struct buf * bp), register struct buf *bp)
+afs_osi_MapStrategy(int (*aproc) (struct buf * bp), struct buf *bp)
 {
     afs_int32 returnCode;
 
@@ -342,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};
@@ -410,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;
@@ -429,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;