diff options
-rw-r--r-- | fs/dcache.c | 8 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 2 | ||||
-rw-r--r-- | fs/ufs/balloc.c | 34 | ||||
-rw-r--r-- | fs/ufs/dir.c | 6 | ||||
-rw-r--r-- | fs/ufs/ialloc.c | 16 | ||||
-rw-r--r-- | fs/ufs/inode.c | 5 | ||||
-rw-r--r-- | fs/ufs/namei.c | 79 | ||||
-rw-r--r-- | fs/ufs/super.c | 11 | ||||
-rw-r--r-- | fs/ufs/ufs.h | 3 |
9 files changed, 85 insertions, 79 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 656ce522a218..37b5afdaf698 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1239,13 +1239,13 @@ ascend: | |||
1239 | /* might go back up the wrong parent if we have had a rename. */ | 1239 | /* might go back up the wrong parent if we have had a rename. */ |
1240 | if (need_seqretry(&rename_lock, seq)) | 1240 | if (need_seqretry(&rename_lock, seq)) |
1241 | goto rename_retry; | 1241 | goto rename_retry; |
1242 | next = child->d_child.next; | 1242 | /* go into the first sibling still alive */ |
1243 | while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { | 1243 | do { |
1244 | next = child->d_child.next; | ||
1244 | if (next == &this_parent->d_subdirs) | 1245 | if (next == &this_parent->d_subdirs) |
1245 | goto ascend; | 1246 | goto ascend; |
1246 | child = list_entry(next, struct dentry, d_child); | 1247 | child = list_entry(next, struct dentry, d_child); |
1247 | next = next->next; | 1248 | } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); |
1248 | } | ||
1249 | rcu_read_unlock(); | 1249 | rcu_read_unlock(); |
1250 | goto resume; | 1250 | goto resume; |
1251 | } | 1251 | } |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 80021c709af9..93575e91a7aa 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -1145,6 +1145,8 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1145 | case 0x00: | 1145 | case 0x00: |
1146 | ncp_dbg(1, "renamed %pd -> %pd\n", | 1146 | ncp_dbg(1, "renamed %pd -> %pd\n", |
1147 | old_dentry, new_dentry); | 1147 | old_dentry, new_dentry); |
1148 | ncp_d_prune(old_dentry); | ||
1149 | ncp_d_prune(new_dentry); | ||
1148 | break; | 1150 | break; |
1149 | case 0x9E: | 1151 | case 0x9E: |
1150 | error = -ENAMETOOLONG; | 1152 | error = -ENAMETOOLONG; |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 2c1036080d52..a7106eda5024 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -51,8 +51,8 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) | |||
51 | 51 | ||
52 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) | 52 | if (ufs_fragnum(fragment) + count > uspi->s_fpg) |
53 | ufs_error (sb, "ufs_free_fragments", "internal error"); | 53 | ufs_error (sb, "ufs_free_fragments", "internal error"); |
54 | 54 | ||
55 | lock_ufs(sb); | 55 | mutex_lock(&UFS_SB(sb)->s_lock); |
56 | 56 | ||
57 | cgno = ufs_dtog(uspi, fragment); | 57 | cgno = ufs_dtog(uspi, fragment); |
58 | bit = ufs_dtogd(uspi, fragment); | 58 | bit = ufs_dtogd(uspi, fragment); |
@@ -115,13 +115,13 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) | |||
115 | if (sb->s_flags & MS_SYNCHRONOUS) | 115 | if (sb->s_flags & MS_SYNCHRONOUS) |
116 | ubh_sync_block(UCPI_UBH(ucpi)); | 116 | ubh_sync_block(UCPI_UBH(ucpi)); |
117 | ufs_mark_sb_dirty(sb); | 117 | ufs_mark_sb_dirty(sb); |
118 | 118 | ||
119 | unlock_ufs(sb); | 119 | mutex_unlock(&UFS_SB(sb)->s_lock); |
120 | UFSD("EXIT\n"); | 120 | UFSD("EXIT\n"); |
121 | return; | 121 | return; |
122 | 122 | ||
123 | failed: | 123 | failed: |
124 | unlock_ufs(sb); | 124 | mutex_unlock(&UFS_SB(sb)->s_lock); |
125 | UFSD("EXIT (FAILED)\n"); | 125 | UFSD("EXIT (FAILED)\n"); |
126 | return; | 126 | return; |
127 | } | 127 | } |
@@ -151,7 +151,7 @@ void ufs_free_blocks(struct inode *inode, u64 fragment, unsigned count) | |||
151 | goto failed; | 151 | goto failed; |
152 | } | 152 | } |
153 | 153 | ||
154 | lock_ufs(sb); | 154 | mutex_lock(&UFS_SB(sb)->s_lock); |
155 | 155 | ||
156 | do_more: | 156 | do_more: |
157 | overflow = 0; | 157 | overflow = 0; |
@@ -211,12 +211,12 @@ do_more: | |||
211 | } | 211 | } |
212 | 212 | ||
213 | ufs_mark_sb_dirty(sb); | 213 | ufs_mark_sb_dirty(sb); |
214 | unlock_ufs(sb); | 214 | mutex_unlock(&UFS_SB(sb)->s_lock); |
215 | UFSD("EXIT\n"); | 215 | UFSD("EXIT\n"); |
216 | return; | 216 | return; |
217 | 217 | ||
218 | failed_unlock: | 218 | failed_unlock: |
219 | unlock_ufs(sb); | 219 | mutex_unlock(&UFS_SB(sb)->s_lock); |
220 | failed: | 220 | failed: |
221 | UFSD("EXIT (FAILED)\n"); | 221 | UFSD("EXIT (FAILED)\n"); |
222 | return; | 222 | return; |
@@ -357,7 +357,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
357 | usb1 = ubh_get_usb_first(uspi); | 357 | usb1 = ubh_get_usb_first(uspi); |
358 | *err = -ENOSPC; | 358 | *err = -ENOSPC; |
359 | 359 | ||
360 | lock_ufs(sb); | 360 | mutex_lock(&UFS_SB(sb)->s_lock); |
361 | tmp = ufs_data_ptr_to_cpu(sb, p); | 361 | tmp = ufs_data_ptr_to_cpu(sb, p); |
362 | 362 | ||
363 | if (count + ufs_fragnum(fragment) > uspi->s_fpb) { | 363 | if (count + ufs_fragnum(fragment) > uspi->s_fpb) { |
@@ -378,19 +378,19 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
378 | "fragment %llu, tmp %llu\n", | 378 | "fragment %llu, tmp %llu\n", |
379 | (unsigned long long)fragment, | 379 | (unsigned long long)fragment, |
380 | (unsigned long long)tmp); | 380 | (unsigned long long)tmp); |
381 | unlock_ufs(sb); | 381 | mutex_unlock(&UFS_SB(sb)->s_lock); |
382 | return INVBLOCK; | 382 | return INVBLOCK; |
383 | } | 383 | } |
384 | if (fragment < UFS_I(inode)->i_lastfrag) { | 384 | if (fragment < UFS_I(inode)->i_lastfrag) { |
385 | UFSD("EXIT (ALREADY ALLOCATED)\n"); | 385 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
386 | unlock_ufs(sb); | 386 | mutex_unlock(&UFS_SB(sb)->s_lock); |
387 | return 0; | 387 | return 0; |
388 | } | 388 | } |
389 | } | 389 | } |
390 | else { | 390 | else { |
391 | if (tmp) { | 391 | if (tmp) { |
392 | UFSD("EXIT (ALREADY ALLOCATED)\n"); | 392 | UFSD("EXIT (ALREADY ALLOCATED)\n"); |
393 | unlock_ufs(sb); | 393 | mutex_unlock(&UFS_SB(sb)->s_lock); |
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
396 | } | 396 | } |
@@ -399,7 +399,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
399 | * There is not enough space for user on the device | 399 | * There is not enough space for user on the device |
400 | */ | 400 | */ |
401 | if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { | 401 | if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) { |
402 | unlock_ufs(sb); | 402 | mutex_unlock(&UFS_SB(sb)->s_lock); |
403 | UFSD("EXIT (FAILED)\n"); | 403 | UFSD("EXIT (FAILED)\n"); |
404 | return 0; | 404 | return 0; |
405 | } | 405 | } |
@@ -424,7 +424,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
424 | ufs_clear_frags(inode, result + oldcount, | 424 | ufs_clear_frags(inode, result + oldcount, |
425 | newcount - oldcount, locked_page != NULL); | 425 | newcount - oldcount, locked_page != NULL); |
426 | } | 426 | } |
427 | unlock_ufs(sb); | 427 | mutex_unlock(&UFS_SB(sb)->s_lock); |
428 | UFSD("EXIT, result %llu\n", (unsigned long long)result); | 428 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
429 | return result; | 429 | return result; |
430 | } | 430 | } |
@@ -439,7 +439,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
439 | fragment + count); | 439 | fragment + count); |
440 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | 440 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, |
441 | locked_page != NULL); | 441 | locked_page != NULL); |
442 | unlock_ufs(sb); | 442 | mutex_unlock(&UFS_SB(sb)->s_lock); |
443 | UFSD("EXIT, result %llu\n", (unsigned long long)result); | 443 | UFSD("EXIT, result %llu\n", (unsigned long long)result); |
444 | return result; | 444 | return result; |
445 | } | 445 | } |
@@ -477,7 +477,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
477 | *err = 0; | 477 | *err = 0; |
478 | UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, | 478 | UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag, |
479 | fragment + count); | 479 | fragment + count); |
480 | unlock_ufs(sb); | 480 | mutex_unlock(&UFS_SB(sb)->s_lock); |
481 | if (newcount < request) | 481 | if (newcount < request) |
482 | ufs_free_fragments (inode, result + newcount, request - newcount); | 482 | ufs_free_fragments (inode, result + newcount, request - newcount); |
483 | ufs_free_fragments (inode, tmp, oldcount); | 483 | ufs_free_fragments (inode, tmp, oldcount); |
@@ -485,7 +485,7 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
485 | return result; | 485 | return result; |
486 | } | 486 | } |
487 | 487 | ||
488 | unlock_ufs(sb); | 488 | mutex_unlock(&UFS_SB(sb)->s_lock); |
489 | UFSD("EXIT (FAILED)\n"); | 489 | UFSD("EXIT (FAILED)\n"); |
490 | return 0; | 490 | return 0; |
491 | } | 491 | } |
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) | |||
87 | 87 | ||
88 | /* Releases the page */ | 88 | /* Releases the page */ |
89 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, | 89 | void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, |
90 | struct page *page, struct inode *inode) | 90 | struct page *page, struct inode *inode, |
91 | bool update_times) | ||
91 | { | 92 | { |
92 | loff_t pos = page_offset(page) + | 93 | loff_t pos = page_offset(page) + |
93 | (char *) de - (char *) page_address(page); | 94 | (char *) de - (char *) page_address(page); |
@@ -103,7 +104,8 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, | |||
103 | 104 | ||
104 | err = ufs_commit_chunk(page, pos, len); | 105 | err = ufs_commit_chunk(page, pos, len); |
105 | ufs_put_page(page); | 106 | ufs_put_page(page); |
106 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 107 | if (update_times) |
108 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | ||
107 | mark_inode_dirty(dir); | 109 | mark_inode_dirty(dir); |
108 | } | 110 | } |
109 | 111 | ||
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 7caa01652888..fd0203ce1f7f 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -69,11 +69,11 @@ void ufs_free_inode (struct inode * inode) | |||
69 | 69 | ||
70 | ino = inode->i_ino; | 70 | ino = inode->i_ino; |
71 | 71 | ||
72 | lock_ufs(sb); | 72 | mutex_lock(&UFS_SB(sb)->s_lock); |
73 | 73 | ||
74 | if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) { | 74 | if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) { |
75 | ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino); | 75 | ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino); |
76 | unlock_ufs(sb); | 76 | mutex_unlock(&UFS_SB(sb)->s_lock); |
77 | return; | 77 | return; |
78 | } | 78 | } |
79 | 79 | ||
@@ -81,7 +81,7 @@ void ufs_free_inode (struct inode * inode) | |||
81 | bit = ufs_inotocgoff (ino); | 81 | bit = ufs_inotocgoff (ino); |
82 | ucpi = ufs_load_cylinder (sb, cg); | 82 | ucpi = ufs_load_cylinder (sb, cg); |
83 | if (!ucpi) { | 83 | if (!ucpi) { |
84 | unlock_ufs(sb); | 84 | mutex_unlock(&UFS_SB(sb)->s_lock); |
85 | return; | 85 | return; |
86 | } | 86 | } |
87 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); | 87 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); |
@@ -115,7 +115,7 @@ void ufs_free_inode (struct inode * inode) | |||
115 | ubh_sync_block(UCPI_UBH(ucpi)); | 115 | ubh_sync_block(UCPI_UBH(ucpi)); |
116 | 116 | ||
117 | ufs_mark_sb_dirty(sb); | 117 | ufs_mark_sb_dirty(sb); |
118 | unlock_ufs(sb); | 118 | mutex_unlock(&UFS_SB(sb)->s_lock); |
119 | UFSD("EXIT\n"); | 119 | UFSD("EXIT\n"); |
120 | } | 120 | } |
121 | 121 | ||
@@ -193,7 +193,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode) | |||
193 | sbi = UFS_SB(sb); | 193 | sbi = UFS_SB(sb); |
194 | uspi = sbi->s_uspi; | 194 | uspi = sbi->s_uspi; |
195 | 195 | ||
196 | lock_ufs(sb); | 196 | mutex_lock(&sbi->s_lock); |
197 | 197 | ||
198 | /* | 198 | /* |
199 | * Try to place the inode in its parent directory | 199 | * Try to place the inode in its parent directory |
@@ -331,21 +331,21 @@ cg_found: | |||
331 | sync_dirty_buffer(bh); | 331 | sync_dirty_buffer(bh); |
332 | brelse(bh); | 332 | brelse(bh); |
333 | } | 333 | } |
334 | unlock_ufs(sb); | 334 | mutex_unlock(&sbi->s_lock); |
335 | 335 | ||
336 | UFSD("allocating inode %lu\n", inode->i_ino); | 336 | UFSD("allocating inode %lu\n", inode->i_ino); |
337 | UFSD("EXIT\n"); | 337 | UFSD("EXIT\n"); |
338 | return inode; | 338 | return inode; |
339 | 339 | ||
340 | fail_remove_inode: | 340 | fail_remove_inode: |
341 | unlock_ufs(sb); | 341 | mutex_unlock(&sbi->s_lock); |
342 | clear_nlink(inode); | 342 | clear_nlink(inode); |
343 | unlock_new_inode(inode); | 343 | unlock_new_inode(inode); |
344 | iput(inode); | 344 | iput(inode); |
345 | UFSD("EXIT (FAILED): err %d\n", err); | 345 | UFSD("EXIT (FAILED): err %d\n", err); |
346 | return ERR_PTR(err); | 346 | return ERR_PTR(err); |
347 | failed: | 347 | failed: |
348 | unlock_ufs(sb); | 348 | mutex_unlock(&sbi->s_lock); |
349 | make_bad_inode(inode); | 349 | make_bad_inode(inode); |
350 | iput (inode); | 350 | iput (inode); |
351 | UFSD("EXIT (FAILED): err %d\n", err); | 351 | UFSD("EXIT (FAILED): err %d\n", err); |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 99aaf5c9bf4d..f913a6924b23 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -903,6 +903,9 @@ void ufs_evict_inode(struct inode * inode) | |||
903 | invalidate_inode_buffers(inode); | 903 | invalidate_inode_buffers(inode); |
904 | clear_inode(inode); | 904 | clear_inode(inode); |
905 | 905 | ||
906 | if (want_delete) | 906 | if (want_delete) { |
907 | lock_ufs(inode->i_sb); | ||
907 | ufs_free_inode(inode); | 908 | ufs_free_inode(inode); |
909 | unlock_ufs(inode->i_sb); | ||
910 | } | ||
908 | } | 911 | } |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index f773deb1d2e3..47966554317c 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -56,11 +56,9 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, unsi | |||
56 | if (dentry->d_name.len > UFS_MAXNAMLEN) | 56 | if (dentry->d_name.len > UFS_MAXNAMLEN) |
57 | return ERR_PTR(-ENAMETOOLONG); | 57 | return ERR_PTR(-ENAMETOOLONG); |
58 | 58 | ||
59 | lock_ufs(dir->i_sb); | ||
60 | ino = ufs_inode_by_name(dir, &dentry->d_name); | 59 | ino = ufs_inode_by_name(dir, &dentry->d_name); |
61 | if (ino) | 60 | if (ino) |
62 | inode = ufs_iget(dir->i_sb, ino); | 61 | inode = ufs_iget(dir->i_sb, ino); |
63 | unlock_ufs(dir->i_sb); | ||
64 | return d_splice_alias(inode, dentry); | 62 | return d_splice_alias(inode, dentry); |
65 | } | 63 | } |
66 | 64 | ||
@@ -76,24 +74,16 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, umode_t mode, | |||
76 | bool excl) | 74 | bool excl) |
77 | { | 75 | { |
78 | struct inode *inode; | 76 | struct inode *inode; |
79 | int err; | ||
80 | |||
81 | UFSD("BEGIN\n"); | ||
82 | 77 | ||
83 | inode = ufs_new_inode(dir, mode); | 78 | inode = ufs_new_inode(dir, mode); |
84 | err = PTR_ERR(inode); | 79 | if (IS_ERR(inode)) |
80 | return PTR_ERR(inode); | ||
85 | 81 | ||
86 | if (!IS_ERR(inode)) { | 82 | inode->i_op = &ufs_file_inode_operations; |
87 | inode->i_op = &ufs_file_inode_operations; | 83 | inode->i_fop = &ufs_file_operations; |
88 | inode->i_fop = &ufs_file_operations; | 84 | inode->i_mapping->a_ops = &ufs_aops; |
89 | inode->i_mapping->a_ops = &ufs_aops; | 85 | mark_inode_dirty(inode); |
90 | mark_inode_dirty(inode); | 86 | return ufs_add_nondir(dentry, inode); |
91 | lock_ufs(dir->i_sb); | ||
92 | err = ufs_add_nondir(dentry, inode); | ||
93 | unlock_ufs(dir->i_sb); | ||
94 | } | ||
95 | UFSD("END: err=%d\n", err); | ||
96 | return err; | ||
97 | } | 87 | } |
98 | 88 | ||
99 | static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) | 89 | static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
@@ -110,9 +100,7 @@ static int ufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev | |||
110 | init_special_inode(inode, mode, rdev); | 100 | init_special_inode(inode, mode, rdev); |
111 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); | 101 | ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); |
112 | mark_inode_dirty(inode); | 102 | mark_inode_dirty(inode); |
113 | lock_ufs(dir->i_sb); | ||
114 | err = ufs_add_nondir(dentry, inode); | 103 | err = ufs_add_nondir(dentry, inode); |
115 | unlock_ufs(dir->i_sb); | ||
116 | } | 104 | } |
117 | return err; | 105 | return err; |
118 | } | 106 | } |
@@ -121,19 +109,18 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
121 | const char * symname) | 109 | const char * symname) |
122 | { | 110 | { |
123 | struct super_block * sb = dir->i_sb; | 111 | struct super_block * sb = dir->i_sb; |
124 | int err = -ENAMETOOLONG; | 112 | int err; |
125 | unsigned l = strlen(symname)+1; | 113 | unsigned l = strlen(symname)+1; |
126 | struct inode * inode; | 114 | struct inode * inode; |
127 | 115 | ||
128 | if (l > sb->s_blocksize) | 116 | if (l > sb->s_blocksize) |
129 | goto out_notlocked; | 117 | return -ENAMETOOLONG; |
130 | 118 | ||
131 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 119 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
132 | err = PTR_ERR(inode); | 120 | err = PTR_ERR(inode); |
133 | if (IS_ERR(inode)) | 121 | if (IS_ERR(inode)) |
134 | goto out_notlocked; | 122 | return err; |
135 | 123 | ||
136 | lock_ufs(dir->i_sb); | ||
137 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { | 124 | if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) { |
138 | /* slow symlink */ | 125 | /* slow symlink */ |
139 | inode->i_op = &ufs_symlink_inode_operations; | 126 | inode->i_op = &ufs_symlink_inode_operations; |
@@ -150,17 +137,13 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
150 | } | 137 | } |
151 | mark_inode_dirty(inode); | 138 | mark_inode_dirty(inode); |
152 | 139 | ||
153 | err = ufs_add_nondir(dentry, inode); | 140 | return ufs_add_nondir(dentry, inode); |
154 | out: | ||
155 | unlock_ufs(dir->i_sb); | ||
156 | out_notlocked: | ||
157 | return err; | ||
158 | 141 | ||
159 | out_fail: | 142 | out_fail: |
160 | inode_dec_link_count(inode); | 143 | inode_dec_link_count(inode); |
161 | unlock_new_inode(inode); | 144 | unlock_new_inode(inode); |
162 | iput(inode); | 145 | iput(inode); |
163 | goto out; | 146 | return err; |
164 | } | 147 | } |
165 | 148 | ||
166 | static int ufs_link (struct dentry * old_dentry, struct inode * dir, | 149 | static int ufs_link (struct dentry * old_dentry, struct inode * dir, |
@@ -169,14 +152,16 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, | |||
169 | struct inode *inode = d_inode(old_dentry); | 152 | struct inode *inode = d_inode(old_dentry); |
170 | int error; | 153 | int error; |
171 | 154 | ||
172 | lock_ufs(dir->i_sb); | ||
173 | |||
174 | inode->i_ctime = CURRENT_TIME_SEC; | 155 | inode->i_ctime = CURRENT_TIME_SEC; |
175 | inode_inc_link_count(inode); | 156 | inode_inc_link_count(inode); |
176 | ihold(inode); | 157 | ihold(inode); |
177 | 158 | ||
178 | error = ufs_add_nondir(dentry, inode); | 159 | error = ufs_add_link(dentry, inode); |
179 | unlock_ufs(dir->i_sb); | 160 | if (error) { |
161 | inode_dec_link_count(inode); | ||
162 | iput(inode); | ||
163 | } else | ||
164 | d_instantiate(dentry, inode); | ||
180 | return error; | 165 | return error; |
181 | } | 166 | } |
182 | 167 | ||
@@ -185,9 +170,12 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
185 | struct inode * inode; | 170 | struct inode * inode; |
186 | int err; | 171 | int err; |
187 | 172 | ||
173 | inode_inc_link_count(dir); | ||
174 | |||
188 | inode = ufs_new_inode(dir, S_IFDIR|mode); | 175 | inode = ufs_new_inode(dir, S_IFDIR|mode); |
176 | err = PTR_ERR(inode); | ||
189 | if (IS_ERR(inode)) | 177 | if (IS_ERR(inode)) |
190 | return PTR_ERR(inode); | 178 | goto out_dir; |
191 | 179 | ||
192 | inode->i_op = &ufs_dir_inode_operations; | 180 | inode->i_op = &ufs_dir_inode_operations; |
193 | inode->i_fop = &ufs_dir_operations; | 181 | inode->i_fop = &ufs_dir_operations; |
@@ -195,9 +183,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
195 | 183 | ||
196 | inode_inc_link_count(inode); | 184 | inode_inc_link_count(inode); |
197 | 185 | ||
198 | lock_ufs(dir->i_sb); | ||
199 | inode_inc_link_count(dir); | ||
200 | |||
201 | err = ufs_make_empty(inode, dir); | 186 | err = ufs_make_empty(inode, dir); |
202 | if (err) | 187 | if (err) |
203 | goto out_fail; | 188 | goto out_fail; |
@@ -205,20 +190,19 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) | |||
205 | err = ufs_add_link(dentry, inode); | 190 | err = ufs_add_link(dentry, inode); |
206 | if (err) | 191 | if (err) |
207 | goto out_fail; | 192 | goto out_fail; |
208 | unlock_ufs(dir->i_sb); | ||
209 | 193 | ||
194 | unlock_new_inode(inode); | ||
210 | d_instantiate(dentry, inode); | 195 | d_instantiate(dentry, inode); |
211 | out: | 196 | return 0; |
212 | return err; | ||
213 | 197 | ||
214 | out_fail: | 198 | out_fail: |
215 | inode_dec_link_count(inode); | 199 | inode_dec_link_count(inode); |
216 | inode_dec_link_count(inode); | 200 | inode_dec_link_count(inode); |
217 | unlock_new_inode(inode); | 201 | unlock_new_inode(inode); |
218 | iput (inode); | 202 | iput (inode); |
203 | out_dir: | ||
219 | inode_dec_link_count(dir); | 204 | inode_dec_link_count(dir); |
220 | unlock_ufs(dir->i_sb); | 205 | return err; |
221 | goto out; | ||
222 | } | 206 | } |
223 | 207 | ||
224 | static int ufs_unlink(struct inode *dir, struct dentry *dentry) | 208 | static int ufs_unlink(struct inode *dir, struct dentry *dentry) |
@@ -248,7 +232,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
248 | struct inode * inode = d_inode(dentry); | 232 | struct inode * inode = d_inode(dentry); |
249 | int err= -ENOTEMPTY; | 233 | int err= -ENOTEMPTY; |
250 | 234 | ||
251 | lock_ufs(dir->i_sb); | ||
252 | if (ufs_empty_dir (inode)) { | 235 | if (ufs_empty_dir (inode)) { |
253 | err = ufs_unlink(dir, dentry); | 236 | err = ufs_unlink(dir, dentry); |
254 | if (!err) { | 237 | if (!err) { |
@@ -257,7 +240,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
257 | inode_dec_link_count(dir); | 240 | inode_dec_link_count(dir); |
258 | } | 241 | } |
259 | } | 242 | } |
260 | unlock_ufs(dir->i_sb); | ||
261 | return err; | 243 | return err; |
262 | } | 244 | } |
263 | 245 | ||
@@ -295,7 +277,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
295 | new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); | 277 | new_de = ufs_find_entry(new_dir, &new_dentry->d_name, &new_page); |
296 | if (!new_de) | 278 | if (!new_de) |
297 | goto out_dir; | 279 | goto out_dir; |
298 | ufs_set_link(new_dir, new_de, new_page, old_inode); | 280 | ufs_set_link(new_dir, new_de, new_page, old_inode, 1); |
299 | new_inode->i_ctime = CURRENT_TIME_SEC; | 281 | new_inode->i_ctime = CURRENT_TIME_SEC; |
300 | if (dir_de) | 282 | if (dir_de) |
301 | drop_nlink(new_inode); | 283 | drop_nlink(new_inode); |
@@ -318,7 +300,12 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
318 | mark_inode_dirty(old_inode); | 300 | mark_inode_dirty(old_inode); |
319 | 301 | ||
320 | if (dir_de) { | 302 | if (dir_de) { |
321 | ufs_set_link(old_inode, dir_de, dir_page, new_dir); | 303 | if (old_dir != new_dir) |
304 | ufs_set_link(old_inode, dir_de, dir_page, new_dir, 0); | ||
305 | else { | ||
306 | kunmap(dir_page); | ||
307 | page_cache_release(dir_page); | ||
308 | } | ||
322 | inode_dec_link_count(old_dir); | 309 | inode_dec_link_count(old_dir); |
323 | } | 310 | } |
324 | return 0; | 311 | return 0; |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index b3bc3e7ae79d..dc33f9416340 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -694,6 +694,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait) | |||
694 | unsigned flags; | 694 | unsigned flags; |
695 | 695 | ||
696 | lock_ufs(sb); | 696 | lock_ufs(sb); |
697 | mutex_lock(&UFS_SB(sb)->s_lock); | ||
697 | 698 | ||
698 | UFSD("ENTER\n"); | 699 | UFSD("ENTER\n"); |
699 | 700 | ||
@@ -711,6 +712,7 @@ static int ufs_sync_fs(struct super_block *sb, int wait) | |||
711 | ufs_put_cstotal(sb); | 712 | ufs_put_cstotal(sb); |
712 | 713 | ||
713 | UFSD("EXIT\n"); | 714 | UFSD("EXIT\n"); |
715 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
714 | unlock_ufs(sb); | 716 | unlock_ufs(sb); |
715 | 717 | ||
716 | return 0; | 718 | return 0; |
@@ -799,6 +801,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) | |||
799 | UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); | 801 | UFSD("flag %u\n", (int)(sb->s_flags & MS_RDONLY)); |
800 | 802 | ||
801 | mutex_init(&sbi->mutex); | 803 | mutex_init(&sbi->mutex); |
804 | mutex_init(&sbi->s_lock); | ||
802 | spin_lock_init(&sbi->work_lock); | 805 | spin_lock_init(&sbi->work_lock); |
803 | INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs); | 806 | INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs); |
804 | /* | 807 | /* |
@@ -1277,6 +1280,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1277 | 1280 | ||
1278 | sync_filesystem(sb); | 1281 | sync_filesystem(sb); |
1279 | lock_ufs(sb); | 1282 | lock_ufs(sb); |
1283 | mutex_lock(&UFS_SB(sb)->s_lock); | ||
1280 | uspi = UFS_SB(sb)->s_uspi; | 1284 | uspi = UFS_SB(sb)->s_uspi; |
1281 | flags = UFS_SB(sb)->s_flags; | 1285 | flags = UFS_SB(sb)->s_flags; |
1282 | usb1 = ubh_get_usb_first(uspi); | 1286 | usb1 = ubh_get_usb_first(uspi); |
@@ -1290,6 +1294,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1290 | new_mount_opt = 0; | 1294 | new_mount_opt = 0; |
1291 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); | 1295 | ufs_set_opt (new_mount_opt, ONERROR_LOCK); |
1292 | if (!ufs_parse_options (data, &new_mount_opt)) { | 1296 | if (!ufs_parse_options (data, &new_mount_opt)) { |
1297 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1293 | unlock_ufs(sb); | 1298 | unlock_ufs(sb); |
1294 | return -EINVAL; | 1299 | return -EINVAL; |
1295 | } | 1300 | } |
@@ -1297,12 +1302,14 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1297 | new_mount_opt |= ufstype; | 1302 | new_mount_opt |= ufstype; |
1298 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { | 1303 | } else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) { |
1299 | pr_err("ufstype can't be changed during remount\n"); | 1304 | pr_err("ufstype can't be changed during remount\n"); |
1305 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1300 | unlock_ufs(sb); | 1306 | unlock_ufs(sb); |
1301 | return -EINVAL; | 1307 | return -EINVAL; |
1302 | } | 1308 | } |
1303 | 1309 | ||
1304 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { | 1310 | if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { |
1305 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1311 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1312 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1306 | unlock_ufs(sb); | 1313 | unlock_ufs(sb); |
1307 | return 0; | 1314 | return 0; |
1308 | } | 1315 | } |
@@ -1326,6 +1333,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1326 | */ | 1333 | */ |
1327 | #ifndef CONFIG_UFS_FS_WRITE | 1334 | #ifndef CONFIG_UFS_FS_WRITE |
1328 | pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n"); | 1335 | pr_err("ufs was compiled with read-only support, can't be mounted as read-write\n"); |
1336 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1329 | unlock_ufs(sb); | 1337 | unlock_ufs(sb); |
1330 | return -EINVAL; | 1338 | return -EINVAL; |
1331 | #else | 1339 | #else |
@@ -1335,11 +1343,13 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1335 | ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && | 1343 | ufstype != UFS_MOUNT_UFSTYPE_SUNx86 && |
1336 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { | 1344 | ufstype != UFS_MOUNT_UFSTYPE_UFS2) { |
1337 | pr_err("this ufstype is read-only supported\n"); | 1345 | pr_err("this ufstype is read-only supported\n"); |
1346 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1338 | unlock_ufs(sb); | 1347 | unlock_ufs(sb); |
1339 | return -EINVAL; | 1348 | return -EINVAL; |
1340 | } | 1349 | } |
1341 | if (!ufs_read_cylinder_structures(sb)) { | 1350 | if (!ufs_read_cylinder_structures(sb)) { |
1342 | pr_err("failed during remounting\n"); | 1351 | pr_err("failed during remounting\n"); |
1352 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1343 | unlock_ufs(sb); | 1353 | unlock_ufs(sb); |
1344 | return -EPERM; | 1354 | return -EPERM; |
1345 | } | 1355 | } |
@@ -1347,6 +1357,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data) | |||
1347 | #endif | 1357 | #endif |
1348 | } | 1358 | } |
1349 | UFS_SB(sb)->s_mount_opt = new_mount_opt; | 1359 | UFS_SB(sb)->s_mount_opt = new_mount_opt; |
1360 | mutex_unlock(&UFS_SB(sb)->s_lock); | ||
1350 | unlock_ufs(sb); | 1361 | unlock_ufs(sb); |
1351 | return 0; | 1362 | return 0; |
1352 | } | 1363 | } |
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index 2a07396d5f9e..2e31ea2e35a3 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h | |||
@@ -30,6 +30,7 @@ struct ufs_sb_info { | |||
30 | int work_queued; /* non-zero if the delayed work is queued */ | 30 | int work_queued; /* non-zero if the delayed work is queued */ |
31 | struct delayed_work sync_work; /* FS sync delayed work */ | 31 | struct delayed_work sync_work; /* FS sync delayed work */ |
32 | spinlock_t work_lock; /* protects sync_work and work_queued */ | 32 | spinlock_t work_lock; /* protects sync_work and work_queued */ |
33 | struct mutex s_lock; | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct ufs_inode_info { | 36 | struct ufs_inode_info { |
@@ -105,7 +106,7 @@ extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page | |||
105 | extern int ufs_empty_dir (struct inode *); | 106 | extern int ufs_empty_dir (struct inode *); |
106 | extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **); | 107 | extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **); |
107 | extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, | 108 | extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, |
108 | struct page *page, struct inode *inode); | 109 | struct page *page, struct inode *inode, bool update_times); |
109 | 110 | ||
110 | /* file.c */ | 111 | /* file.c */ |
111 | extern const struct inode_operations ufs_file_inode_operations; | 112 | extern const struct inode_operations ufs_file_inode_operations; |