]> err.no Git - linux-2.6/blobdiff - fs/ntfs/inode.c
[PATCH] exportfs: add find_acceptable_alias helper
[linux-2.6] / fs / ntfs / inode.c
index b24f4c4b2c5ccff9e80a8018ceb56b296b7ae74c..ea1bd3feea1b7dac830a03fd55ef41d2dfe15a9b 100644 (file)
@@ -2125,13 +2125,13 @@ void ntfs_put_inode(struct inode *vi)
                ntfs_inode *ni = NTFS_I(vi);
                if (NInoIndexAllocPresent(ni)) {
                        struct inode *bvi = NULL;
-                       down(&vi->i_sem);
+                       mutex_lock(&vi->i_mutex);
                        if (atomic_read(&vi->i_count) == 2) {
                                bvi = ni->itype.index.bmp_ino;
                                if (bvi)
                                        ni->itype.index.bmp_ino = NULL;
                        }
-                       up(&vi->i_sem);
+                       mutex_unlock(&vi->i_mutex);
                        if (bvi)
                                iput(bvi);
                }
@@ -2311,7 +2311,7 @@ static const char *es = "  Leaving inconsistent metadata.  Unmount and run "
  *
  * Returns 0 on success or -errno on error.
  *
- * Called with ->i_sem held.  In all but one case ->i_alloc_sem is held for
+ * Called with ->i_mutex held.  In all but one case ->i_alloc_sem is held for
  * writing.  The only case in the kernel where ->i_alloc_sem is not held is
  * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called
  * with the current i_size as the offset.  The analogous place in NTFS is in
@@ -2767,7 +2767,25 @@ unm_done:
        up_write(&ni->runlist.lock);
 done:
        /* Update the mtime and ctime on the base inode. */
-       inode_update_time(VFS_I(base_ni), 1);
+       /* normally ->truncate shouldn't update ctime or mtime,
+        * but ntfs did before so it got a copy & paste version
+        * of file_update_time.  one day someone should fix this
+        * for real.
+        */
+       if (!IS_NOCMTIME(VFS_I(base_ni)) && !IS_RDONLY(VFS_I(base_ni))) {
+               struct timespec now = current_fs_time(VFS_I(base_ni)->i_sb);
+               int sync_it = 0;
+
+               if (!timespec_equal(&VFS_I(base_ni)->i_mtime, &now) ||
+                   !timespec_equal(&VFS_I(base_ni)->i_ctime, &now))
+                       sync_it = 1;
+               VFS_I(base_ni)->i_mtime = now;
+               VFS_I(base_ni)->i_ctime = now;
+
+               if (sync_it)
+                       mark_inode_dirty_sync(VFS_I(base_ni));
+       }
+
        if (likely(!err)) {
                NInoClearTruncateFailed(ni);
                ntfs_debug("Done.");
@@ -2831,7 +2849,7 @@ void ntfs_truncate_vfs(struct inode *vi) {
  * We also abort all changes of user, group, and mode as we do not implement
  * the NTFS ACLs yet.
  *
- * Called with ->i_sem held.  For the ATTR_SIZE (i.e. ->truncate) case, also
+ * Called with ->i_mutex held.  For the ATTR_SIZE (i.e. ->truncate) case, also
  * called with ->i_alloc_sem held for writing.
  *
  * Basically this is a copy of generic notify_change() and inode_setattr()