Linux: use override_creds when available
[openafs.git] / src / afs / LINUX / osi_file.c
index a920b81..7a14729 100644 (file)
 #include "osi_compat.h"
 
 #ifndef CURRENT_TIME
-# ifdef IATTR_TAKES_64BIT_TIME
-#  define CURRENT_TIME         (current_kernel_time64())
+# if defined(HAVE_LINUX_KTIME_GET_COARSE_REAL_TS64)
+#   define AFS_CURRENT_TIME(x) (ktime_get_coarse_real_ts64((x)))
 # else
-#  define CURRENT_TIME            (current_kernel_time())
+#  ifdef IATTR_TAKES_64BIT_TIME
+#    define AFS_CURRENT_TIME(x) do {*(x) = current_kernel_time64();} while (0)
+#  else
+#    define AFS_CURRENT_TIME(x) do {*(x) = current_kernel_time();} while (0)
+#  endif
 # endif
+#else
+# define AFS_CURRENT_TIME(x) do {*(x) = CURRENT_TIME;} while(0)
 #endif
 
 int cache_fh_type = -1;
@@ -53,6 +59,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
     struct inode *tip = NULL;
     struct dentry *dp = NULL;
     struct file* filp;
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    const struct cred *cur_cred;
+#endif
 
     dp = afs_get_dentry_from_fh(afs_cacheSBp, ainode, cache_fh_len, cache_fh_type,
                afs_fh_acceptable);
@@ -61,6 +70,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
     tip = dp->d_inode;
     tip->i_flags |= S_NOATIME; /* Disable updating access times. */
 
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    cur_cred = override_creds(cache_creds);
+#endif
 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
     /* Use stashed credentials - prevent selinux/apparmor problems  */
     filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, cache_creds);
@@ -69,6 +81,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
 #else
     filp = dentry_open(dget(dp), mntget(afs_cacheMnt), O_RDWR);
 #endif
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    revert_creds(cur_cred);
+#endif
     if (IS_ERR(filp)) {
        afs_warn("afs: Cannot open cache file (code %d). Trying to continue, "
                  "but AFS accesses may return errors or panic the system\n",
@@ -92,7 +107,6 @@ osi_UFSOpen(afs_dcache_id_t *ainode)
        osi_Panic("UFSOpen called for non-UFS cache\n");
     }
     if (!afs_osicred_initialized) {
-       /* valid for SunOS, Ultrix */
        memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
        crhold(&afs_osi_cred);  /* don't let it evaporate, since it is static */
        afs_osicred_initialized = 1;
@@ -163,10 +177,20 @@ afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
 int
 osi_UFSClose(struct osi_file *afile)
 {
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    const struct cred *cur_cred;
+#endif
+
     AFS_STATCNT(osi_Close);
     if (afile) {
        if (OSIFILE_INODE(afile)) {
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+           cur_cred = override_creds(cache_creds);
+#endif
            filp_close(afile->filp, NULL);
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+           revert_creds(cur_cred);
+#endif
        }
     }
     kfree(afile);
@@ -180,12 +204,18 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
     struct osi_stat tstat;
     struct iattr newattrs;
     struct inode *inode = OSIFILE_INODE(afile);
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    const struct cred *cur_cred;
+#endif
     AFS_STATCNT(osi_Truncate);
 
     /* This routine only shrinks files, and most systems
      * have very slow truncates, even when the file is already
      * small enough.  Check now and save some time.
      */
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    cur_cred = override_creds(cache_creds);
+#endif
     code = afs_osi_Stat(afile, &tstat);
     if (code || tstat.size <= asize)
        return code;
@@ -196,7 +226,7 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
 #endif
     newattrs.ia_size = asize;
     newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-    newattrs.ia_ctime = CURRENT_TIME;
+    AFS_CURRENT_TIME(&newattrs.ia_ctime);
 
     /* avoid notify_change() since it wants to update dentry->d_parent */
 #ifdef HAVE_LINUX_SETATTR_PREPARE
@@ -213,6 +243,9 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
     up_write(&inode->i_alloc_sem);
 #endif
     afs_linux_unlock_inode(inode);
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    revert_creds(cur_cred);
+#endif
     AFS_GLOCK();
     return code;
 }
@@ -374,6 +407,9 @@ osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw)
     size_t count;
     unsigned long savelim;
     loff_t pos;
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    const struct cred *cur_cred = override_creds(cache_creds);
+#endif
 
     savelim = current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur;
     current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
@@ -429,6 +465,9 @@ osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw)
 #endif /* AFS_FILE_NEEDS_SET_FS */
 
     current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = savelim;
+#if defined(HAVE_LINUX_OVERRIDE_CREDS)
+    revert_creds(cur_cred);
+#endif
 
     return code;
 }