All of lore.kernel.org
 help / color / mirror / Atom feed
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.