From: Alexander Nyberg <alexn@dsv.su.se>
To: andrea@novell.com, akpm@osdl.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] Make msync update atime and possibly ctime/mtime
Date: Sun, 05 Dec 2004 19:57:49 +0100 [thread overview]
Message-ID: <1102273070.725.170.camel@boxen> (raw)
There's an issue that doing the sequence of
open; mmap; change file; possibly msync; munmap; close;
I know this is still a problem if the user doesn't do msync,
but I have not yet figured out a good way to do it without msync.
This should help us a bit on the way.
http://www.opengroup.org/onlinepubs/007908799/xsh/msync.html says that:
"If msync() causes any write to a file, the file's st_ctime and
st_mtime fields are marked for update."
I think it makes a good time to update the atime of the file
aswell as it won't get done anywhere else.
Signed-off-by: Alexander Nyberg <alexn@dsv.su.se>
===== mm/msync.c 1.19 vs edited =====
--- 1.19/mm/msync.c 2004-10-19 07:26:38 +02:00
+++ edited/mm/msync.c 2004-12-04 22:48:54 +01:00
@@ -27,15 +27,16 @@ static int filemap_sync_pte(pte_t *ptep,
pte_t pte = *ptep;
unsigned long pfn = pte_pfn(pte);
struct page *page;
+ int dirty = 0;
if (pte_present(pte) && pfn_valid(pfn)) {
page = pfn_to_page(pfn);
if (!PageReserved(page) &&
- (ptep_clear_flush_dirty(vma, address, ptep) ||
+ ((dirty = ptep_clear_flush_dirty(vma, address, ptep)) ||
page_test_and_clear_dirty(page)))
set_page_dirty(page);
}
- return 0;
+ return dirty;
}
static int filemap_sync_pte_range(pmd_t * pmd,
@@ -43,7 +44,7 @@ static int filemap_sync_pte_range(pmd_t
struct vm_area_struct *vma, unsigned int flags)
{
pte_t *pte;
- int error;
+ int dirty = 0;
if (pmd_none(*pmd))
return 0;
@@ -55,16 +56,16 @@ static int filemap_sync_pte_range(pmd_t
pte = pte_offset_map(pmd, address);
if ((address & PMD_MASK) != (end & PMD_MASK))
end = (address & PMD_MASK) + PMD_SIZE;
- error = 0;
+
do {
- error |= filemap_sync_pte(pte, vma, address, flags);
+ dirty |= filemap_sync_pte(pte, vma, address, flags);
address += PAGE_SIZE;
pte++;
} while (address && (address < end));
pte_unmap(pte - 1);
- return error;
+ return dirty;
}
static inline int filemap_sync_pmd_range(pgd_t * pgd,
@@ -72,7 +73,7 @@ static inline int filemap_sync_pmd_range
struct vm_area_struct *vma, unsigned int flags)
{
pmd_t * pmd;
- int error;
+ int dirty = 0;
if (pgd_none(*pgd))
return 0;
@@ -84,13 +85,13 @@ static inline int filemap_sync_pmd_range
pmd = pmd_offset(pgd, address);
if ((address & PGDIR_MASK) != (end & PGDIR_MASK))
end = (address & PGDIR_MASK) + PGDIR_SIZE;
- error = 0;
+
do {
- error |= filemap_sync_pte_range(pmd, address, end, vma, flags);
+ dirty |= filemap_sync_pte_range(pmd, address, end, vma, flags);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address && (address < end));
- return error;
+ return dirty;
}
static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
@@ -98,7 +99,7 @@ static int filemap_sync(struct vm_area_s
{
pgd_t * dir;
unsigned long end = address + size;
- int error = 0;
+ int dirty = 0;
/* Aquire the lock early; it may be possible to avoid dropping
* and reaquiring it repeatedly.
@@ -117,7 +118,7 @@ static int filemap_sync(struct vm_area_s
if (address >= end)
BUG();
do {
- error |= filemap_sync_pmd_range(dir, address, end, vma, flags);
+ dirty |= filemap_sync_pmd_range(dir, address, end, vma, flags);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
@@ -129,7 +130,7 @@ static int filemap_sync(struct vm_area_s
out:
spin_unlock(&vma->vm_mm->page_table_lock);
- return error;
+ return dirty;
}
/*
@@ -146,17 +147,17 @@ static int filemap_sync(struct vm_area_s
static int msync_interval(struct vm_area_struct * vma,
unsigned long start, unsigned long end, int flags)
{
- int ret = 0;
+ int dirty, ret = 0;
struct file * file = vma->vm_file;
if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED))
return -EBUSY;
if (file && (vma->vm_flags & VM_SHARED)) {
- ret = filemap_sync(vma, start, end-start, flags);
+ struct address_space *mapping = file->f_mapping;
+ dirty = filemap_sync(vma, start, end-start, flags);
- if (!ret && (flags & MS_SYNC)) {
- struct address_space *mapping = file->f_mapping;
+ if (flags & MS_SYNC) {
int err;
down(&mapping->host->i_sem);
@@ -171,6 +172,11 @@ static int msync_interval(struct vm_area
ret = err;
up(&mapping->host->i_sem);
}
+
+ /* only update ctime & mtime if file actually changed */
+ if (dirty)
+ inode_update_time(mapping->host, 1);
+ update_atime(mapping->host);
}
return ret;
}
reply other threads:[~2004-12-05 18:58 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1102273070.725.170.camel@boxen \
--to=alexn@dsv.su.se \
--cc=akpm@osdl.org \
--cc=andrea@novell.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.