bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] hurd/libdiskfs: I added in the `relatime' mount option.


From: Ryan Jeffrey
Subject: [PATCH] hurd/libdiskfs: I added in the `relatime' mount option.
Date: Thu, 10 Sep 2020 14:01:58 -0700
User-agent: mu4e 1.4.13; emacs 27.1

Using Linux as a guide, I implemented the `relatime' mount option as mentioned 
in the Hurd's Contributing page.

diff -ruN a/hurd/libdiskfs/conch-fetch.c b/hurd/libdiskfs/conch-fetch.c
--- a/hurd/libdiskfs/conch-fetch.c      2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/conch-fetch.c      2020-09-09 15:32:43.000000000 -0700
@@ -58,7 +58,7 @@
          cred->po->np->dn_set_mtime = 1;
          mod = 1;
        }
-      if (cred->mapped->accessed && ! _diskfs_noatime)
+      if (cred->mapped->accessed && atime_should_update (cred->po->np))
        {
          cred->po->np->dn_set_atime = 1;
          mod = 1;
diff -ruN a/hurd/libdiskfs/diskfs.h b/hurd/libdiskfs/diskfs.h
--- a/hurd/libdiskfs/diskfs.h   2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/diskfs.h   2020-09-09 23:49:31.000000000 -0700
@@ -1046,7 +1046,9 @@
 diskfs_init_dir (struct node *dp, struct node *pdp, struct protid *cred);
 
 /* If disk is not readonly and the noatime option is not enabled, set
-   NP->dn_set_atime.  */
+   NP->dn_set_atime.  If relatime is enabled, only set NP->dn_set_atime
+   if the atime has not been updated today, or if ctime or mtime are
+   more recent than atime */
 void diskfs_set_node_atime (struct node *np);
 
 /* If NP->dn_set_ctime is set, then modify NP->dn_stat.st_ctim
diff -ruN a/hurd/libdiskfs/file-statfs.c b/hurd/libdiskfs/file-statfs.c
--- a/hurd/libdiskfs/file-statfs.c      2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/file-statfs.c      2020-09-08 02:21:25.000000000 -0700
@@ -43,6 +43,8 @@
     statbuf->f_flag |= ST_SYNCHRONOUS;
   if (_diskfs_noatime)
     statbuf->f_flag |= ST_NOATIME;
+  else if (_diskfs_relatime)
+    statbuf->f_flag |= ST_RELATIME;
 
   diskfs_set_statfs (statbuf);
 
diff -ruN a/hurd/libdiskfs/init-init.c b/hurd/libdiskfs/init-init.c
--- a/hurd/libdiskfs/init-init.c        2020-09-10 02:49:31.000000000 -0700
+++ b/hurd/libdiskfs/init-init.c        2020-09-06 22:24:18.000000000 -0700
@@ -38,6 +38,7 @@
 
 int _diskfs_nosuid, _diskfs_noexec;
 int _diskfs_noatime;
+int _diskfs_relatime;
 
 struct hurd_port _diskfs_exec_portcell;
 
diff -ruN a/hurd/libdiskfs/node-times.c b/hurd/libdiskfs/node-times.c
--- a/hurd/libdiskfs/node-times.c       2020-09-10 02:49:31.000000000 -0700
+++ b/hurd/libdiskfs/node-times.c       2020-09-09 23:47:15.000000000 -0700
@@ -24,12 +24,48 @@
 #include "priv.h"
 #include <maptime.h>
 
+/* If the disk is not readonly and noatime is not set, then check relatime
+   conditions: if either `np->dn_stat.st_mtim.tv_sec' or
+   `np->dn_stat.st_ctim.tv_sec' is less than `np->dn_stat.st_atim.tv_sec',
+   or if the atime is greater than 24 hours old, return true.
+   */
+int
+atime_should_update (struct node *np)
+{
+  if (_diskfs_noatime)
+    return 0;
+
+  if (_diskfs_relatime)
+    {
+      /* Update atime if mtime is younger than atime. */
+      if (np->dn_stat.st_mtim.tv_sec > np->dn_stat.st_atim.tv_sec)
+        return 1;
+      /* Update atime if ctime is younger than atime. */
+      else if (np->dn_stat.st_ctim.tv_sec > np->dn_stat.st_atim.tv_sec)
+        return 1;
+      /* Update atime if current atime is more than 24 hours old. */
+      else
+      {
+        struct timeval t;
+        maptime_read (diskfs_mtime, &t);
+        if ((long)(t.tv_sec - np->dn_stat.st_atim.tv_sec) >= 24 * 60 * 60)
+            return 1;
+      }
+      return 0;
+    }
+
+  return 1; /* strictatime */
+}
+
 /* If disk is not readonly and the noatime option is not enabled, set
-   NP->dn_set_atime.  */
+   NP->dn_set_atime.  If relatime is enabled, only set NP->dn_set_atime
+   if the atime has not been updated today, or if ctime or mtime are
+   more recent than atime */
 void
 diskfs_set_node_atime (struct node *np)
 {
-  if (!_diskfs_noatime && !diskfs_check_readonly ())
+  np->dn_set_atime = 0;
+  if (!diskfs_check_readonly () && atime_should_update (np))
     np->dn_set_atime = 1;
 }
 
diff -ruN a/hurd/libdiskfs/opts-append-std.c b/hurd/libdiskfs/opts-append-std.c
--- a/hurd/libdiskfs/opts-append-std.c  2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/opts-append-std.c  2020-09-09 15:06:06.000000000 -0700
@@ -42,6 +42,8 @@
     err = argz_add (argz, argz_len, "--no-exec");
   if (!err && _diskfs_noatime)
     err = argz_add (argz, argz_len, "--no-atime");
+  else if (!err && _diskfs_relatime)
+    err = argz_add (argz, argz_len, "--relatime");
   if (!err && _diskfs_no_inherit_dir_group)
     err = argz_add (argz, argz_len, "--no-inherit-dir-group");
 
diff -ruN a/hurd/libdiskfs/opts-common.c b/hurd/libdiskfs/opts-common.c
--- a/hurd/libdiskfs/opts-common.c      2020-09-10 02:49:31.000000000 -0700
+++ b/hurd/libdiskfs/opts-common.c      2020-09-07 00:31:48.000000000 -0700
@@ -47,6 +47,7 @@
    "Do not update file access times on disk for reads"},
   {"noatime",  0,   0, OPTION_ALIAS | OPTION_HIDDEN},
   {"atime", OPT_ATIME, 0, 0, "Do update file access times for reads normally"},
+  {"strictatime", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
   {"no-inherit-dir-group", OPT_NO_INHERIT_DIR_GROUP, 0, 0,
    "Create new nodes with gid of the process"},
   {"nogrpid",    0,   0, OPTION_ALIAS | OPTION_HIDDEN},
@@ -55,5 +56,8 @@
    "Create new nodes with gid of parent dir"},
   {"grpid",    0,   0, OPTION_ALIAS | OPTION_HIDDEN},
   {"bsdgroups", 0,   0, OPTION_ALIAS | OPTION_HIDDEN},
+  {"relatime", 'R', 0, 0,
+    "Only update access times once daily or if older than change time "
+    "or modification time."},
   {0, 0}
 };
diff -ruN a/hurd/libdiskfs/opts-std-runtime.c 
b/hurd/libdiskfs/opts-std-runtime.c
--- a/hurd/libdiskfs/opts-std-runtime.c 2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/opts-std-runtime.c 2020-09-09 01:06:22.000000000 -0700
@@ -33,7 +33,7 @@
 struct parse_hook
 {
   int readonly, sync, sync_interval, remount, nosuid, noexec, noatime,
-    noinheritdirgroup;
+    noinheritdirgroup, relatime;
 };
 
 /* Implement the options in H, and free H.  */
@@ -80,6 +80,8 @@
     _diskfs_noexec = h->noexec;
   if (h->noatime != -1)
     _diskfs_noatime = h->noatime;
+  else if (h->relatime != -1)
+    _diskfs_relatime = h->relatime;
   if (h->noinheritdirgroup != -1)
     _diskfs_no_inherit_dir_group = h->noinheritdirgroup;
 
@@ -100,10 +102,16 @@
     case 'u': h->remount = 1; break;
     case 'S': h->nosuid = 1; break;
     case 'E': h->noexec = 1; break;
-    case 'A': h->noatime = 1; break;
+    case 'A':
+    {
+      h->relatime = -1;
+      h->noatime = 1;
+      break;
+    }
+    case 'R': h->relatime = 1; break;
     case OPT_SUID_OK: h->nosuid = 0; break;
     case OPT_EXEC_OK: h->noexec = 0; break;
-    case OPT_ATIME: h->noatime = 0; break;
+    case OPT_ATIME: h->noatime = h->relatime = 0; break;
     case OPT_NO_INHERIT_DIR_GROUP: h->noinheritdirgroup = 1; break;
     case OPT_INHERIT_DIR_GROUP: h->noinheritdirgroup = 0; break;
     case 'n': h->sync_interval = 0; h->sync = 0; break;
@@ -129,7 +137,7 @@
          h->sync = diskfs_synchronous;
          h->sync_interval = -1;
          h->remount = 0;
-         h->nosuid = h->noexec = h->noatime = h->noinheritdirgroup = -1;
+         h->nosuid = h->noexec = h->noatime = h->noinheritdirgroup = 
h->relatime = -1;
 
          /* We know that we have one child, with which we share our hook.  */
          state->child_inputs[0] = h;
diff -ruN a/hurd/libdiskfs/opts-std-startup.c 
b/hurd/libdiskfs/opts-std-startup.c
--- a/hurd/libdiskfs/opts-std-startup.c 2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/opts-std-startup.c 2020-09-07 16:10:31.000000000 -0700
@@ -86,10 +86,22 @@
       TOGGLE (diskfs_readonly, 'r', 'w');
       TOGGLE (_diskfs_nosuid, 'S', OPT_SUID_OK);
       TOGGLE (_diskfs_noexec, 'E', OPT_EXEC_OK);
-      TOGGLE (_diskfs_noatime, 'A', OPT_ATIME);
       TOGGLE (_diskfs_no_inherit_dir_group, OPT_NO_INHERIT_DIR_GROUP,
              OPT_INHERIT_DIR_GROUP);
 #undef TOGGLE
+    /* The next three cases must be done manually to avoid duplicates */
+    case 'A':
+      _diskfs_noatime = 1;
+      break;
+
+    case 'R':
+      _diskfs_relatime = 1;
+      break;
+
+    case OPT_ATIME: /* strictatime. */
+      _diskfs_noatime = 0;
+      _diskfs_relatime = 0;
+      break;
 
     case 's':
       if (arg == NULL)
diff -ruN a/hurd/libdiskfs/priv.h b/hurd/libdiskfs/priv.h
--- a/hurd/libdiskfs/priv.h     2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/priv.h     2020-09-09 23:50:09.000000000 -0700
@@ -38,6 +38,10 @@
 /* This relaxes the requirement to set `st_atim'.  */
 extern int _diskfs_noatime;
 
+/* Will set `st_atim' if it has not been updated in 24 hours or
+   if `st_ctim' or `st_mtim' are younger than `st_atim'.  */
+extern int _diskfs_relatime;
+
 /* This enables SysV style group behaviour.  New nodes inherit the GID
    of the user creating them unless the SGID bit is set of the parent
    directory.  */
@@ -98,6 +102,13 @@
    links, then request soft references to be dropped.  */
 void _diskfs_lastref (struct node *np);
 
+/* If the disk is not readonly and noatime is not set, then check relatime
+   conditions: if either `np->dn_stat.st_mtim.tv_sec' or
+   `np->dn_stat.st_ctim.tv_sec' is less than `np->dn_stat.st_atim.tv_sec',
+   or if the atime is greater than 24 hours old, return true.
+   */
+int atime_should_update (struct node *np);
+
 /* Number of outstanding PT_CTL ports. */
 extern int _diskfs_ncontrol_ports;
 
diff -ruN a/hurd/libdiskfs/rdwr-internal.c b/hurd/libdiskfs/rdwr-internal.c
--- a/hurd/libdiskfs/rdwr-internal.c    2020-07-18 12:08:35.000000000 -0700
+++ b/hurd/libdiskfs/rdwr-internal.c    2020-09-09 15:34:40.000000000 -0700
@@ -49,7 +49,7 @@
     {
       if (dir)
        np->dn_set_mtime = 1;
-      else if (! _diskfs_noatime)
+      else if (atime_should_update (np))
        np->dn_set_atime = 1;
     }
 
@@ -70,7 +70,7 @@
     {
       if (dir)
        np->dn_set_mtime = 1;
-      else if (!_diskfs_noatime)
+      else if (atime_should_update (np))
        np->dn_set_atime = 1;
     }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]