[patch] O_NOATIME open() flag

marekm@i17linuxb.ists.pwr.wroc.pl
Mon, 16 Nov 1998 17:32:16 +0100 (CET)


This patch adds the O_NOATIME open() flag. Quoting the glibc manual:

- Macro: int O_NOATIME
If this bit is set, `read' will not update the access time of the
file. *Note File Times::. This is used by programs that do
backups, so that backing a file up does not count as reading it.
Only the owner of the file or the superuser may use this bit.

This is a GNU extension.

It could also be used by programs that access lots of files, want
maximum speed and don't care about file access times (such as news
servers). It works just like "mount -o noatime", but only applies
to individual files, not the whole filesystem.

Please consider including this small patch in the official kernel.
It also updates some of my old information about NCSA telnet.
This is my second attempt to send this patch (the first time I didn't
get it back from the mailing list). Please Cc: any replies to me.

Thanks,
Marek

[patch follows]
diff -urN v2.1.128/linux/CREDITS linux/CREDITS
--- v2.1.128/linux/CREDITS Sat Nov 14 20:24:39 1998
+++ linux/CREDITS Sat Nov 14 20:37:47 1998
@@ -1241,6 +1241,15 @@
S: Victoria 3163
S: Australia

+N: Marek Michalkiewicz
+E: marekm@piast.t19.ml.org
+P: 1024/813CA711 D4 D6 F6 30 51 23 B5 C9 D3 0D 87 76 EC 07 45 8F
+D: O_NOATIME open() flag, other minor hacks.
+D: Maintainer of the shadow password suite.
+S: Olsztynska 7A/16
+S: 80-395 Gdansk
+S: Poland
+
N: Pauline Middelink
E: middelin@polyware.iaf.nl
D: General low-level bug fixes, /proc fixes, identd support
diff -urN v2.1.128/linux/Documentation/networking/ncsa-telnet linux/Documentation/networking/ncsa-telnet
--- v2.1.128/linux/Documentation/networking/ncsa-telnet Tue Apr 30 11:42:36 1996
+++ linux/Documentation/networking/ncsa-telnet Sat Nov 14 20:37:47 1998
@@ -3,14 +3,13 @@
such as Solaris.

The following information is courtesy of
-Marek <marekm@i17linuxb.ists.pwr.wroc.pl>
+Marek Michalkiewicz <marekm@piast.t19.ml.org>

-There is a fixed version somewhere on ftp.upe.ac.za (sorry, I don't
-remember the exact pathname, and this site is very slow from here).
-It may or may not be faster for you to get it from
-ftp://ftp.ists.pwr.wroc.pl/pub/msdos/telnet/ncsa_upe/tel23074.zip
+There used to be a fixed version of NCSA telnet available from
+ftp.upe.ac.za, but this site doesn't seem to exist anymore.
+You can still get it from
+ftp://ftp.ists.pwr.wroc.pl/pub/msdos/tel23074.zip
(source is in v230704s.zip). I have tested it with 1.3.79 (with
path mtu discovery enabled - ncsa 2.3.08 didn't work) and it seems
to work. I don't know if anyone is working on this code - this
-version is over a year old. Too bad - it's faster and often more
-stable than these windoze telnets, and runs on almost anything...
+version is over 2 years old.
diff -urN v2.1.128/linux/drivers/char/random.c linux/drivers/char/random.c
--- v2.1.128/linux/drivers/char/random.c Wed Nov 4 19:02:24 1998
+++ linux/drivers/char/random.c Sat Nov 14 20:37:47 1998
@@ -1333,7 +1333,7 @@
/*
* If we gave the user some bytes, update the access time.
*/
- if (count != 0) {
+ if ((count != 0) && !(file->f_flags & O_NOATIME)) {
UPDATE_ATIME(file->f_dentry->d_inode);
}

diff -urN v2.1.128/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.1.128/linux/fs/ext2/dir.c Sat Nov 14 20:24:49 1998
+++ linux/fs/ext2/dir.c Sat Nov 14 20:37:47 1998
@@ -215,6 +215,7 @@
offset = 0;
brelse (bh);
}
- UPDATE_ATIME(inode);
+ if (!(filp->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);
return 0;
}
diff -urN v2.1.128/linux/fs/fcntl.c linux/fs/fcntl.c
--- v2.1.128/linux/fs/fcntl.c Wed Nov 4 19:02:04 1998
+++ linux/fs/fcntl.c Sat Nov 14 20:37:47 1998
@@ -82,7 +82,7 @@
return ret;
}

-#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
+#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_NOATIME)

static int setfl(int fd, struct file * filp, unsigned long arg)
{
@@ -94,6 +94,12 @@
*/
if (!(arg & O_APPEND) && IS_APPEND(inode))
return -EPERM;
+
+ /* O_NOATIME can only be set by the owner or superuser */
+ if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME)) {
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+ }

/* Did FASYNC state change? */
if ((arg ^ filp->f_flags) & FASYNC) {
diff -urN v2.1.128/linux/fs/minix/dir.c linux/fs/minix/dir.c
--- v2.1.128/linux/fs/minix/dir.c Sat Nov 14 20:24:52 1998
+++ linux/fs/minix/dir.c Sat Nov 14 20:37:47 1998
@@ -94,6 +94,7 @@
} while (offset < 1024 && filp->f_pos < inode->i_size);
brelse(bh);
}
- UPDATE_ATIME(inode);
+ if (!(filp->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);
return 0;
}
diff -urN v2.1.128/linux/fs/namei.c linux/fs/namei.c
--- v2.1.128/linux/fs/namei.c Sat Nov 14 20:24:17 1998
+++ linux/fs/namei.c Sat Nov 14 20:37:47 1998
@@ -668,6 +668,11 @@
goto exit;
}

+ if (flag & O_NOATIME) {
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ goto exit;
+ }
+
if (flag & O_TRUNC) {
error = get_write_access(inode);
if (error)
diff -urN v2.1.128/linux/fs/pipe.c linux/fs/pipe.c
--- v2.1.128/linux/fs/pipe.c Wed Nov 4 19:01:35 1998
+++ linux/fs/pipe.c Sat Nov 14 20:37:47 1998
@@ -80,7 +80,8 @@
PIPE_LOCK(*inode)--;
wake_up_interruptible(&PIPE_WAIT(*inode));
if (read) {
- UPDATE_ATIME(inode);
+ if (!(filp->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);
return read;
}
if (PIPE_WRITERS(*inode))
diff -urN v2.1.128/linux/fs/qnx4/dir.c linux/fs/qnx4/dir.c
--- v2.1.128/linux/fs/qnx4/dir.c Tue Sep 1 19:43:13 1998
+++ linux/fs/qnx4/dir.c Sat Nov 14 20:37:47 1998
@@ -68,7 +68,8 @@
brelse(bh);
blknum++;
}
- UPDATE_ATIME(inode);
+ if (!(filp->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);

return 0;
}
diff -urN v2.1.128/linux/fs/ufs/dir.c linux/fs/ufs/dir.c
--- v2.1.128/linux/fs/ufs/dir.c Sat Nov 14 20:24:52 1998
+++ linux/fs/ufs/dir.c Sat Nov 14 20:37:47 1998
@@ -149,7 +149,8 @@
offset = 0;
brelse (bh);
}
- UPDATE_ATIME(inode);
+ if (!(filp->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);
return 0;
}

diff -urN v2.1.128/linux/include/asm-alpha/fcntl.h linux/include/asm-alpha/fcntl.h
--- v2.1.128/linux/include/asm-alpha/fcntl.h Wed Nov 4 19:03:05 1998
+++ linux/include/asm-alpha/fcntl.h Sat Nov 14 20:37:47 1998
@@ -20,6 +20,7 @@
#define O_DIRECT 040000 /* direct disk access - should check with OSF/1 */
#define O_DIRECTORY 0100000 /* must be a directory */
#define O_NOFOLLOW 0200000 /* don't follow links */
+#define O_NOATIME 0400000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/include/asm-arm/fcntl.h linux/include/asm-arm/fcntl.h
--- v2.1.128/linux/include/asm-arm/fcntl.h Wed Nov 4 19:03:05 1998
+++ linux/include/asm-arm/fcntl.h Sat Nov 14 20:37:47 1998
@@ -18,6 +18,7 @@
#define FASYNC 020000 /* fcntl, for BSD compatibility */
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_NOATIME 0200000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/include/asm-i386/fcntl.h linux/include/asm-i386/fcntl.h
--- v2.1.128/linux/include/asm-i386/fcntl.h Wed Nov 4 19:03:05 1998
+++ linux/include/asm-i386/fcntl.h Sat Nov 14 20:37:47 1998
@@ -20,6 +20,7 @@
#define O_LARGEFILE 0100000
#define O_DIRECTORY 0200000 /* must be a directory */
#define O_NOFOLLOW 0400000 /* don't follow links */
+#define O_NOATIME 01000000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/include/asm-m68k/fcntl.h linux/include/asm-m68k/fcntl.h
--- v2.1.128/linux/include/asm-m68k/fcntl.h Wed Nov 4 19:03:05 1998
+++ linux/include/asm-m68k/fcntl.h Sat Nov 14 20:37:47 1998
@@ -18,6 +18,7 @@
#define FASYNC 020000 /* fcntl, for BSD compatibility */
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_NOATIME 0200000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/include/asm-mips/fcntl.h linux/include/asm-mips/fcntl.h
--- v2.1.128/linux/include/asm-mips/fcntl.h Wed Nov 4 19:03:08 1998
+++ linux/include/asm-mips/fcntl.h Sat Nov 14 20:37:47 1998
@@ -27,6 +27,7 @@
#define O_NOFOLLOW 0x4000 /* Don't follow symbolic links */
#define O_DIRECT 0x8000 /* direct disk access hint - currently ignored */
#define O_DIRECTORY 0x10000 /* must be a directory */
+#define O_NOATIME 0x20000 /* don't update atime */

#define O_NDELAY O_NONBLOCK

diff -urN v2.1.128/linux/include/asm-ppc/fcntl.h linux/include/asm-ppc/fcntl.h
--- v2.1.128/linux/include/asm-ppc/fcntl.h Wed Nov 4 19:03:09 1998
+++ linux/include/asm-ppc/fcntl.h Sat Nov 14 20:37:47 1998
@@ -18,6 +18,7 @@
#define FASYNC 020000 /* fcntl, for BSD compatibility */
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_NOATIME 0200000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/include/asm-sparc/fcntl.h linux/include/asm-sparc/fcntl.h
--- v2.1.128/linux/include/asm-sparc/fcntl.h Sat Nov 14 20:24:19 1998
+++ linux/include/asm-sparc/fcntl.h Sat Nov 14 20:37:47 1998
@@ -19,6 +19,7 @@
#define O_NOCTTY 0x8000 /* not fcntl */
#define O_DIRECTORY 0x10000 /* must be a directory */
#define O_NOFOLLOW 0x20000 /* don't follow links */
+#define O_NOATIME 0x40000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/include/asm-sparc64/fcntl.h linux/include/asm-sparc64/fcntl.h
--- v2.1.128/linux/include/asm-sparc64/fcntl.h Sat Nov 14 20:24:19 1998
+++ linux/include/asm-sparc64/fcntl.h Sat Nov 14 20:37:47 1998
@@ -19,6 +19,7 @@
#define O_NOCTTY 0x8000 /* not fcntl */
#define O_DIRECTORY 0x10000 /* must be a directory */
#define O_NOFOLLOW 0x20000 /* don't follow links */
+#define O_NOATIME 0x40000 /* don't update atime */

#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff -urN v2.1.128/linux/mm/filemap.c linux/mm/filemap.c
--- v2.1.128/linux/mm/filemap.c Sat Nov 14 20:24:53 1998
+++ linux/mm/filemap.c Sat Nov 14 20:37:47 1998
@@ -805,7 +805,8 @@
filp->f_reada = 1;
if (page_cache)
free_page(page_cache);
- UPDATE_ATIME(inode);
+ if (!(filp->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);
}

static int file_read_actor(read_descriptor_t * desc, const char *area, unsigned long size)
@@ -1406,7 +1407,8 @@
return -EACCES;
if (!inode->i_op || !inode->i_op->readpage)
return -ENOEXEC;
- UPDATE_ATIME(inode);
+ if (!(file->f_flags & O_NOATIME))
+ UPDATE_ATIME(inode);
vma->vm_file = file;
file->f_count++;
vma->vm_ops = ops;
[end of patch]

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/