diff options
Diffstat (limited to 'fs/ufs')
| -rw-r--r-- | fs/ufs/balloc.c | 8 | ||||
| -rw-r--r-- | fs/ufs/ialloc.c | 4 | ||||
| -rw-r--r-- | fs/ufs/namei.c | 4 | ||||
| -rw-r--r-- | fs/ufs/super.c | 148 | ||||
| -rw-r--r-- | fs/ufs/ufs.h | 5 | ||||
| -rw-r--r-- | fs/ufs/ufs_fs.h | 1 |
6 files changed, 96 insertions, 74 deletions
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 42694e11c23d..1b3e410bf334 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
| @@ -116,7 +116,7 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) | |||
| 116 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 116 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
| 117 | if (sb->s_flags & MS_SYNCHRONOUS) | 117 | if (sb->s_flags & MS_SYNCHRONOUS) |
| 118 | ubh_sync_block(UCPI_UBH(ucpi)); | 118 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 119 | sb->s_dirt = 1; | 119 | ufs_mark_sb_dirty(sb); |
| 120 | 120 | ||
| 121 | unlock_super (sb); | 121 | unlock_super (sb); |
| 122 | UFSD("EXIT\n"); | 122 | UFSD("EXIT\n"); |
| @@ -214,7 +214,7 @@ do_more: | |||
| 214 | goto do_more; | 214 | goto do_more; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | sb->s_dirt = 1; | 217 | ufs_mark_sb_dirty(sb); |
| 218 | unlock_super (sb); | 218 | unlock_super (sb); |
| 219 | UFSD("EXIT\n"); | 219 | UFSD("EXIT\n"); |
| 220 | return; | 220 | return; |
| @@ -557,7 +557,7 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment, | |||
| 557 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 557 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
| 558 | if (sb->s_flags & MS_SYNCHRONOUS) | 558 | if (sb->s_flags & MS_SYNCHRONOUS) |
| 559 | ubh_sync_block(UCPI_UBH(ucpi)); | 559 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 560 | sb->s_dirt = 1; | 560 | ufs_mark_sb_dirty(sb); |
| 561 | 561 | ||
| 562 | UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment); | 562 | UFSD("EXIT, fragment %llu\n", (unsigned long long)fragment); |
| 563 | 563 | ||
| @@ -677,7 +677,7 @@ succed: | |||
| 677 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 677 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
| 678 | if (sb->s_flags & MS_SYNCHRONOUS) | 678 | if (sb->s_flags & MS_SYNCHRONOUS) |
| 679 | ubh_sync_block(UCPI_UBH(ucpi)); | 679 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 680 | sb->s_dirt = 1; | 680 | ufs_mark_sb_dirty(sb); |
| 681 | 681 | ||
| 682 | result += cgno * uspi->s_fpg; | 682 | result += cgno * uspi->s_fpg; |
| 683 | UFSD("EXIT3, result %llu\n", (unsigned long long)result); | 683 | UFSD("EXIT3, result %llu\n", (unsigned long long)result); |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 4ec5c1085a87..e84cbe21b986 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
| @@ -116,7 +116,7 @@ void ufs_free_inode (struct inode * inode) | |||
| 116 | if (sb->s_flags & MS_SYNCHRONOUS) | 116 | if (sb->s_flags & MS_SYNCHRONOUS) |
| 117 | ubh_sync_block(UCPI_UBH(ucpi)); | 117 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 118 | 118 | ||
| 119 | sb->s_dirt = 1; | 119 | ufs_mark_sb_dirty(sb); |
| 120 | unlock_super (sb); | 120 | unlock_super (sb); |
| 121 | UFSD("EXIT\n"); | 121 | UFSD("EXIT\n"); |
| 122 | } | 122 | } |
| @@ -288,7 +288,7 @@ cg_found: | |||
| 288 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); | 288 | ubh_mark_buffer_dirty (UCPI_UBH(ucpi)); |
| 289 | if (sb->s_flags & MS_SYNCHRONOUS) | 289 | if (sb->s_flags & MS_SYNCHRONOUS) |
| 290 | ubh_sync_block(UCPI_UBH(ucpi)); | 290 | ubh_sync_block(UCPI_UBH(ucpi)); |
| 291 | sb->s_dirt = 1; | 291 | ufs_mark_sb_dirty(sb); |
| 292 | 292 | ||
| 293 | inode->i_ino = cg * uspi->s_ipg + bit; | 293 | inode->i_ino = cg * uspi->s_ipg + bit; |
| 294 | inode_init_owner(inode, dir, mode); | 294 | inode_init_owner(inode, dir, mode); |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index a2281cadefa1..90d74b8f8eba 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
| @@ -46,7 +46,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) | |||
| 46 | return err; | 46 | return err; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 49 | static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags) |
| 50 | { | 50 | { |
| 51 | struct inode * inode = NULL; | 51 | struct inode * inode = NULL; |
| 52 | ino_t ino; | 52 | ino_t ino; |
| @@ -71,7 +71,7 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru | |||
| 71 | * with d_instantiate(). | 71 | * with d_instantiate(). |
| 72 | */ | 72 | */ |
| 73 | static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, | 73 | static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, |
| 74 | struct nameidata *nd) | 74 | bool excl) |
| 75 | { | 75 | { |
| 76 | struct inode *inode; | 76 | struct inode *inode; |
| 77 | int err; | 77 | int err; |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 302f340d0071..444927e5706b 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
| @@ -302,7 +302,7 @@ void ufs_error (struct super_block * sb, const char * function, | |||
| 302 | if (!(sb->s_flags & MS_RDONLY)) { | 302 | if (!(sb->s_flags & MS_RDONLY)) { |
| 303 | usb1->fs_clean = UFS_FSBAD; | 303 | usb1->fs_clean = UFS_FSBAD; |
| 304 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); | 304 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); |
| 305 | sb->s_dirt = 1; | 305 | ufs_mark_sb_dirty(sb); |
| 306 | sb->s_flags |= MS_RDONLY; | 306 | sb->s_flags |= MS_RDONLY; |
| 307 | } | 307 | } |
| 308 | va_start (args, fmt); | 308 | va_start (args, fmt); |
| @@ -334,7 +334,7 @@ void ufs_panic (struct super_block * sb, const char * function, | |||
| 334 | if (!(sb->s_flags & MS_RDONLY)) { | 334 | if (!(sb->s_flags & MS_RDONLY)) { |
| 335 | usb1->fs_clean = UFS_FSBAD; | 335 | usb1->fs_clean = UFS_FSBAD; |
| 336 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); | 336 | ubh_mark_buffer_dirty(USPI_UBH(uspi)); |
| 337 | sb->s_dirt = 1; | 337 | ufs_mark_sb_dirty(sb); |
| 338 | } | 338 | } |
| 339 | va_start (args, fmt); | 339 | va_start (args, fmt); |
| 340 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); | 340 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
| @@ -691,6 +691,83 @@ static void ufs_put_super_internal(struct super_block *sb) | |||
| 691 | UFSD("EXIT\n"); | 691 | UFSD("EXIT\n"); |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | static int ufs_sync_fs(struct super_block *sb, int wait) | ||
| 695 | { | ||
| 696 | struct ufs_sb_private_info * uspi; | ||
| 697 | struct ufs_super_block_first * usb1; | ||
| 698 | struct ufs_super_block_third * usb3; | ||
| 699 | unsigned flags; | ||
| 700 | |||
| 701 | lock_ufs(sb); | ||
| 702 | lock_super(sb); | ||
| 703 | |||
| 704 | UFSD("ENTER\n"); | ||
| 705 | |||
| 706 | flags = UFS_SB(sb)->s_flags; | ||
| 707 | uspi = UFS_SB(sb)->s_uspi; | ||
| 708 | usb1 = ubh_get_usb_first(uspi); | ||
| 709 | usb3 = ubh_get_usb_third(uspi); | ||
| 710 | |||
| 711 | usb1->fs_time = cpu_to_fs32(sb, get_seconds()); | ||
| 712 | if ((flags & UFS_ST_MASK) == UFS_ST_SUN || | ||
| 713 | (flags & UFS_ST_MASK) == UFS_ST_SUNOS || | ||
| 714 | (flags & UFS_ST_MASK) == UFS_ST_SUNx86) | ||
| 715 | ufs_set_fs_state(sb, usb1, usb3, | ||
| 716 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); | ||
| 717 | ufs_put_cstotal(sb); | ||
| 718 | |||
| 719 | UFSD("EXIT\n"); | ||
| 720 | unlock_super(sb); | ||
| 721 | unlock_ufs(sb); | ||
| 722 | |||
| 723 | return 0; | ||
| 724 | } | ||
| 725 | |||
| 726 | static void delayed_sync_fs(struct work_struct *work) | ||
| 727 | { | ||
| 728 | struct ufs_sb_info *sbi; | ||
| 729 | |||
| 730 | sbi = container_of(work, struct ufs_sb_info, sync_work.work); | ||
| 731 | |||
| 732 | spin_lock(&sbi->work_lock); | ||
| 733 | sbi->work_queued = 0; | ||
| 734 | spin_unlock(&sbi->work_lock); | ||
| 735 | |||
| 736 | ufs_sync_fs(sbi->sb, 1); | ||
| 737 | } | ||
| 738 | |||
| 739 | void ufs_mark_sb_dirty(struct super_block *sb) | ||
| 740 | { | ||
| 741 | struct ufs_sb_info *sbi = UFS_SB(sb); | ||
| 742 | unsigned long delay; | ||
| 743 | |||
| 744 | spin_lock(&sbi->work_lock); | ||
| 745 | if (!sbi->work_queued) { | ||
| 746 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
| 747 | queue_delayed_work(system_long_wq, &sbi->sync_work, delay); | ||
| 748 | sbi->work_queued = 1; | ||
| 749 | } | ||
| 750 | spin_unlock(&sbi->work_lock); | ||
| 751 | } | ||
| 752 | |||
| 753 | static void ufs_put_super(struct super_block *sb) | ||
| 754 | { | ||
| 755 | struct ufs_sb_info * sbi = UFS_SB(sb); | ||
| 756 | |||
| 757 | UFSD("ENTER\n"); | ||
| 758 | |||
| 759 | if (!(sb->s_flags & MS_RDONLY)) | ||
| 760 | ufs_put_super_internal(sb); | ||
| 761 | cancel_delayed_work_sync(&sbi->sync_work); | ||
| 762 | |||
| 763 | ubh_brelse_uspi (sbi->s_uspi); | ||
| 764 | kfree (sbi->s_uspi); | ||
| 765 | kfree (sbi); | ||
| 766 | sb->s_fs_info = NULL; | ||
| 767 | UFSD("EXIT\n"); | ||
| 768 | return; | ||
| 769 | } | ||
| 770 | |||
| 694 | static int ufs_fill_super(struct super_block *sb, void *data, int silent) | 771 | static int ufs_fill_super(struct super_block *sb, void *data, int silent) |
| 695 | { | 772 | { |
| 696 | struct ufs_sb_info * sbi; | 773 | struct ufs_sb_info * sbi; |
| @@ -716,6 +793,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 716 | if (!sbi) | 793 | if (!sbi) |
| 717 | goto failed_nomem; | 794 | goto failed_nomem; |
| 718 | sb->s_fs_info = sbi; | 795 | sb->s_fs_info = sbi; |
| 796 | sbi->sb = sb; | ||
| 719 | 797 | ||
| 720 | UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); | 798 | UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); |
| 721 | 799 | ||
| @@ -727,6 +805,8 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 727 | } | 805 | } |
| 728 | #endif | 806 | #endif |
| 729 | mutex_init(&sbi->mutex); | 807 | mutex_init(&sbi->mutex); |
| 808 | spin_lock_init(&sbi->work_lock); | ||
| 809 | INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs); | ||
| 730 | /* | 810 | /* |
| 731 | * Set default mount options | 811 | * Set default mount options |
| 732 | * Parse mount options | 812 | * Parse mount options |
| @@ -1191,68 +1271,6 @@ failed_nomem: | |||
| 1191 | return -ENOMEM; | 1271 | return -ENOMEM; |
| 1192 | } | 1272 | } |
| 1193 | 1273 | ||
| 1194 | static int ufs_sync_fs(struct super_block *sb, int wait) | ||
| 1195 | { | ||
| 1196 | struct ufs_sb_private_info * uspi; | ||
| 1197 | struct ufs_super_block_first * usb1; | ||
| 1198 | struct ufs_super_block_third * usb3; | ||
| 1199 | unsigned flags; | ||
| 1200 | |||
| 1201 | lock_ufs(sb); | ||
| 1202 | lock_super(sb); | ||
| 1203 | |||
| 1204 | UFSD("ENTER\n"); | ||
| 1205 | |||
| 1206 | flags = UFS_SB(sb)->s_flags; | ||
| 1207 | uspi = UFS_SB(sb)->s_uspi; | ||
| 1208 | usb1 = ubh_get_usb_first(uspi); | ||
| 1209 | usb3 = ubh_get_usb_third(uspi); | ||
| 1210 | |||
| 1211 | usb1->fs_time = cpu_to_fs32(sb, get_seconds()); | ||
| 1212 | if ((flags & UFS_ST_MASK) == UFS_ST_SUN || | ||
| 1213 | (flags & UFS_ST_MASK) == UFS_ST_SUNOS || | ||
| 1214 | (flags & UFS_ST_MASK) == UFS_ST_SUNx86) | ||
| 1215 | ufs_set_fs_state(sb, usb1, usb3, | ||
| 1216 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); | ||
| 1217 | ufs_put_cstotal(sb); | ||
| 1218 | sb->s_dirt = 0; | ||
| 1219 | |||
| 1220 | UFSD("EXIT\n"); | ||
| 1221 | unlock_super(sb); | ||
| 1222 | unlock_ufs(sb); | ||
| 1223 | |||
| 1224 | return 0; | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | static void ufs_write_super(struct super_block *sb) | ||
| 1228 | { | ||
| 1229 | if (!(sb->s_flags & MS_RDONLY)) | ||
| 1230 | ufs_sync_fs(sb, 1); | ||
| 1231 | else | ||
| 1232 | sb->s_dirt = 0; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | static void ufs_put_super(struct super_block *sb) | ||
| 1236 | { | ||
| 1237 | struct ufs_sb_info * sbi = UFS_SB(sb); | ||
| 1238 | |||
| 1239 | UFSD("ENTER\n"); | ||
| 1240 | |||
| 1241 | if (sb->s_dirt) | ||
| 1242 | ufs_write_super(sb); | ||
| 1243 | |||
| 1244 | if (!(sb->s_flags & MS_RDONLY)) | ||
| 1245 | ufs_put_super_internal(sb); | ||
| 1246 | |||
| 1247 | ubh_brelse_uspi (sbi->s_uspi); | ||
| 1248 | kfree (sbi->s_uspi); | ||
| 1249 | kfree (sbi); | ||
| 1250 | sb->s_fs_info = NULL; | ||
| 1251 | UFSD("EXIT\n"); | ||
| 1252 | return; | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | |||
| 1256 | static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | 1274 | static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) |
| 1257 | { | 1275 | { |
| 1258 | struct ufs_sb_private_info * uspi; | 1276 | struct ufs_sb_private_info * uspi; |
| @@ -1308,7 +1326,6 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
| 1308 | ufs_set_fs_state(sb, usb1, usb3, | 1326 | ufs_set_fs_state(sb, usb1, usb3, |
| 1309 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); | 1327 | UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)); |
| 1310 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); | 1328 | ubh_mark_buffer_dirty (USPI_UBH(uspi)); |
| 1311 | sb->s_dirt = 0; | ||
| 1312 | sb->s_flags |= MS_RDONLY; | 1329 | sb->s_flags |= MS_RDONLY; |
| 1313 | } else { | 1330 | } else { |
| 1314 | /* | 1331 | /* |
| @@ -1458,7 +1475,6 @@ static const struct super_operations ufs_super_ops = { | |||
| 1458 | .write_inode = ufs_write_inode, | 1475 | .write_inode = ufs_write_inode, |
| 1459 | .evict_inode = ufs_evict_inode, | 1476 | .evict_inode = ufs_evict_inode, |
| 1460 | .put_super = ufs_put_super, | 1477 | .put_super = ufs_put_super, |
| 1461 | .write_super = ufs_write_super, | ||
| 1462 | .sync_fs = ufs_sync_fs, | 1478 | .sync_fs = ufs_sync_fs, |
| 1463 | .statfs = ufs_statfs, | 1479 | .statfs = ufs_statfs, |
| 1464 | .remount_fs = ufs_remount, | 1480 | .remount_fs = ufs_remount, |
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index 528750b7e701..343e6fc571e5 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h | |||
| @@ -20,6 +20,10 @@ struct ufs_sb_info { | |||
| 20 | unsigned s_mount_opt; | 20 | unsigned s_mount_opt; |
| 21 | struct mutex mutex; | 21 | struct mutex mutex; |
| 22 | struct task_struct *mutex_owner; | 22 | struct task_struct *mutex_owner; |
| 23 | struct super_block *sb; | ||
| 24 | int work_queued; /* non-zero if the delayed work is queued */ | ||
| 25 | struct delayed_work sync_work; /* FS sync delayed work */ | ||
| 26 | spinlock_t work_lock; /* protects sync_work and work_queued */ | ||
| 23 | }; | 27 | }; |
| 24 | 28 | ||
| 25 | struct ufs_inode_info { | 29 | struct ufs_inode_info { |
| @@ -123,6 +127,7 @@ extern __printf(3, 4) | |||
| 123 | void ufs_error(struct super_block *, const char *, const char *, ...); | 127 | void ufs_error(struct super_block *, const char *, const char *, ...); |
| 124 | extern __printf(3, 4) | 128 | extern __printf(3, 4) |
| 125 | void ufs_panic(struct super_block *, const char *, const char *, ...); | 129 | void ufs_panic(struct super_block *, const char *, const char *, ...); |
| 130 | void ufs_mark_sb_dirty(struct super_block *sb); | ||
| 126 | 131 | ||
| 127 | /* symlink.c */ | 132 | /* symlink.c */ |
| 128 | extern const struct inode_operations ufs_fast_symlink_inode_operations; | 133 | extern const struct inode_operations ufs_fast_symlink_inode_operations; |
diff --git a/fs/ufs/ufs_fs.h b/fs/ufs/ufs_fs.h index 8aba544f9fad..0cbd5d340b67 100644 --- a/fs/ufs/ufs_fs.h +++ b/fs/ufs/ufs_fs.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
| 35 | #include <linux/stat.h> | 35 | #include <linux/stat.h> |
| 36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
| 37 | #include <linux/workqueue.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/div64.h> | 39 | #include <asm/div64.h> |
| 39 | typedef __u64 __bitwise __fs64; | 40 | typedef __u64 __bitwise __fs64; |
