summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2015-06-16 01:56:23 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-06-16 02:08:34 -0400
commit70d45cdb664390a5573c05f1eecc8432dcc6581b (patch)
tree6ab7b1d46459aa7c872a156d36ffc6416e8c9464
parenta50e4a02ad6957ef6f77cccaa8ef6a337f1856af (diff)
downloadlinux-70d45cdb664390a5573c05f1eecc8432dcc6581b.tar.gz
linux-70d45cdb664390a5573c05f1eecc8432dcc6581b.tar.bz2
linux-70d45cdb664390a5573c05f1eecc8432dcc6581b.zip
ufs: don't touch mtime/ctime of directory being moved
See "ext2: Do not update mtime of a moved directory" (and followup in "ext2: fix unbalanced kmap()/kunmap()") for background; this is UFS equivalent - the same problem exists here. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ufs/dir.c6
-rw-r--r--fs/ufs/namei.c9
-rw-r--r--fs/ufs/ufs.h2
3 files changed, 12 insertions, 5 deletions
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 1bfe8cabff0f..862d284d438e 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -87,7 +87,8 @@ ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
/* Releases the page */
void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
- struct page *page, struct inode *inode)
+ struct page *page, struct inode *inode,
+ bool update_times)
{
loff_t pos = page_offset(page) +
(char *) de - (char *) page_address(page);
@@ -103,7 +104,8 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
err = ufs_commit_chunk(page, pos, len);
ufs_put_page(page);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
+ if (update_times)
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
}
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 3429079c11e2..d3fdfa22add5 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -276,7 +276,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page);
if (!new_de)
goto out_dir;
- ufs_set_link(new_dir, new_de, new_page, old_inode);
+ ufs_set_link(new_dir, new_de, new_page, old_inode, 1);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
drop_nlink(new_inode);
@@ -299,7 +299,12 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
mark_inode_dirty(old_inode);
if (dir_de) {
- ufs_set_link(old_inode, dir_de, dir_page, new_dir);
+ if (old_dir != new_dir)
+ ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0);
+ else {
+ kunmap(dir_page);
+ page_cache_release(dir_page);
+ }
inode_dec_link_count(old_dir);
}
return 0;
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index cf6368d42d4a..2e31ea2e35a3 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -106,7 +106,7 @@ extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page
extern int ufs_empty_dir (struct inode *);
extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
- struct page *page, struct inode *inode);
+ struct page *page, struct inode *inode, bool update_times);
/* file.c */
extern const struct inode_operations ufs_file_inode_operations;