Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'work.minix' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull minix updates from Al Viro:
"Assorted fixes - mostly Christoph's"

* 'work.minix' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
minix_rename(): minix_delete_entry() might fail
minix: don't flush page immediately for DIRSYNC directories
minix: fix error handling in minix_set_link
minix: fix error handling in minix_delete_entry
minix: move releasing pages into unlink and rename
minix: make minix_new_inode() return error as ERR_PTR(-E...)

+91 -92
+6 -10
fs/minix/bitmap.c
··· 210 210 mark_buffer_dirty(bh); 211 211 } 212 212 213 - struct inode *minix_new_inode(const struct inode *dir, umode_t mode, int *error) 213 + struct inode *minix_new_inode(const struct inode *dir, umode_t mode) 214 214 { 215 215 struct super_block *sb = dir->i_sb; 216 216 struct minix_sb_info *sbi = minix_sb(sb); ··· 220 220 unsigned long j; 221 221 int i; 222 222 223 - if (!inode) { 224 - *error = -ENOMEM; 225 - return NULL; 226 - } 223 + if (!inode) 224 + return ERR_PTR(-ENOMEM); 227 225 j = bits_per_zone; 228 226 bh = NULL; 229 - *error = -ENOSPC; 230 227 spin_lock(&bitmap_lock); 231 228 for (i = 0; i < sbi->s_imap_blocks; i++) { 232 229 bh = sbi->s_imap[i]; ··· 234 237 if (!bh || j >= bits_per_zone) { 235 238 spin_unlock(&bitmap_lock); 236 239 iput(inode); 237 - return NULL; 240 + return ERR_PTR(-ENOSPC); 238 241 } 239 242 if (minix_test_and_set_bit(j, bh->b_data)) { /* shouldn't happen */ 240 243 spin_unlock(&bitmap_lock); 241 244 printk("minix_new_inode: bit already set\n"); 242 245 iput(inode); 243 - return NULL; 246 + return ERR_PTR(-ENOSPC); 244 247 } 245 248 spin_unlock(&bitmap_lock); 246 249 mark_buffer_dirty(bh); 247 250 j += i * bits_per_zone; 248 251 if (!j || j > sbi->s_ninodes) { 249 252 iput(inode); 250 - return NULL; 253 + return ERR_PTR(-ENOSPC); 251 254 } 252 255 inode_init_owner(&nop_mnt_idmap, inode, dir, mode); 253 256 inode->i_ino = j; ··· 257 260 insert_inode_hash(inode); 258 261 mark_inode_dirty(inode); 259 262 260 - *error = 0; 261 263 return inode; 262 264 } 263 265
+34 -28
fs/minix/dir.c
··· 46 46 return last_byte; 47 47 } 48 48 49 - static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len) 49 + static void dir_commit_chunk(struct page *page, loff_t pos, unsigned len) 50 50 { 51 51 struct address_space *mapping = page->mapping; 52 52 struct inode *dir = mapping->host; 53 - int err = 0; 53 + 54 54 block_write_end(NULL, mapping, pos, len, len, page, NULL); 55 55 56 56 if (pos+len > dir->i_size) { 57 57 i_size_write(dir, pos+len); 58 58 mark_inode_dirty(dir); 59 59 } 60 - if (IS_DIRSYNC(dir)) 61 - err = write_one_page(page); 62 - else 63 - unlock_page(page); 60 + unlock_page(page); 61 + } 62 + 63 + static int minix_handle_dirsync(struct inode *dir) 64 + { 65 + int err; 66 + 67 + err = filemap_write_and_wait(dir->i_mapping); 68 + if (!err) 69 + err = sync_inode_metadata(dir, 1); 64 70 return err; 65 71 } 66 72 ··· 280 274 memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2); 281 275 de->inode = inode->i_ino; 282 276 } 283 - err = dir_commit_chunk(page, pos, sbi->s_dirsize); 277 + dir_commit_chunk(page, pos, sbi->s_dirsize); 284 278 dir->i_mtime = dir->i_ctime = current_time(dir); 285 279 mark_inode_dirty(dir); 280 + err = minix_handle_dirsync(dir); 286 281 out_put: 287 282 dir_put_page(page); 288 283 out: ··· 304 297 305 298 lock_page(page); 306 299 err = minix_prepare_chunk(page, pos, len); 307 - if (err == 0) { 308 - if (sbi->s_version == MINIX_V3) 309 - ((minix3_dirent *) de)->inode = 0; 310 - else 311 - de->inode = 0; 312 - err = dir_commit_chunk(page, pos, len); 313 - } else { 300 + if (err) { 314 301 unlock_page(page); 302 + return err; 315 303 } 316 - dir_put_page(page); 304 + if (sbi->s_version == MINIX_V3) 305 + ((minix3_dirent *)de)->inode = 0; 306 + else 307 + de->inode = 0; 308 + dir_commit_chunk(page, pos, len); 317 309 inode->i_ctime = inode->i_mtime = current_time(inode); 318 310 mark_inode_dirty(inode); 319 - return err; 311 + return minix_handle_dirsync(inode); 320 312 } 321 313 322 314 int minix_make_empty(struct inode *inode, struct inode *dir) ··· 355 349 } 356 350 kunmap_atomic(kaddr); 357 351 358 - err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); 352 + dir_commit_chunk(page, 0, 2 * sbi->s_dirsize); 353 + err = minix_handle_dirsync(inode); 359 354 fail: 360 355 put_page(page); 361 356 return err; ··· 416 409 } 417 410 418 411 /* Releases the page */ 419 - void minix_set_link(struct minix_dir_entry *de, struct page *page, 420 - struct inode *inode) 412 + int minix_set_link(struct minix_dir_entry *de, struct page *page, 413 + struct inode *inode) 421 414 { 422 415 struct inode *dir = page->mapping->host; 423 416 struct minix_sb_info *sbi = minix_sb(dir->i_sb); ··· 426 419 int err; 427 420 428 421 lock_page(page); 429 - 430 422 err = minix_prepare_chunk(page, pos, sbi->s_dirsize); 431 - if (err == 0) { 432 - if (sbi->s_version == MINIX_V3) 433 - ((minix3_dirent *) de)->inode = inode->i_ino; 434 - else 435 - de->inode = inode->i_ino; 436 - err = dir_commit_chunk(page, pos, sbi->s_dirsize); 437 - } else { 423 + if (err) { 438 424 unlock_page(page); 425 + return err; 439 426 } 440 - dir_put_page(page); 427 + if (sbi->s_version == MINIX_V3) 428 + ((minix3_dirent *)de)->inode = inode->i_ino; 429 + else 430 + de->inode = inode->i_ino; 431 + dir_commit_chunk(page, pos, sbi->s_dirsize); 441 432 dir->i_mtime = dir->i_ctime = current_time(dir); 442 433 mark_inode_dirty(dir); 434 + return minix_handle_dirsync(dir); 443 435 } 444 436 445 437 struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)
+3 -2
fs/minix/minix.h
··· 45 45 extern struct inode *minix_iget(struct super_block *, unsigned long); 46 46 extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **); 47 47 extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); 48 - extern struct inode * minix_new_inode(const struct inode *, umode_t, int *); 48 + extern struct inode * minix_new_inode(const struct inode *, umode_t); 49 49 extern void minix_free_inode(struct inode * inode); 50 50 extern unsigned long minix_count_free_inodes(struct super_block *sb); 51 51 extern int minix_new_block(struct inode * inode); ··· 69 69 extern int minix_delete_entry(struct minix_dir_entry*, struct page*); 70 70 extern int minix_make_empty(struct inode*, struct inode*); 71 71 extern int minix_empty_dir(struct inode*); 72 - extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*); 72 + int minix_set_link(struct minix_dir_entry *de, struct page *page, 73 + struct inode *inode); 73 74 extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**); 74 75 extern ino_t minix_inode_by_name(struct dentry*); 75 76
+48 -52
fs/minix/namei.c
··· 36 36 static int minix_mknod(struct mnt_idmap *idmap, struct inode *dir, 37 37 struct dentry *dentry, umode_t mode, dev_t rdev) 38 38 { 39 - int error; 40 39 struct inode *inode; 41 40 42 41 if (!old_valid_dev(rdev)) 43 42 return -EINVAL; 44 43 45 - inode = minix_new_inode(dir, mode, &error); 44 + inode = minix_new_inode(dir, mode); 45 + if (IS_ERR(inode)) 46 + return PTR_ERR(inode); 46 47 47 - if (inode) { 48 - minix_set_inode(inode, rdev); 49 - mark_inode_dirty(inode); 50 - error = add_nondir(dentry, inode); 51 - } 52 - return error; 48 + minix_set_inode(inode, rdev); 49 + mark_inode_dirty(inode); 50 + return add_nondir(dentry, inode); 53 51 } 54 52 55 53 static int minix_tmpfile(struct mnt_idmap *idmap, struct inode *dir, 56 54 struct file *file, umode_t mode) 57 55 { 58 - int error; 59 - struct inode *inode = minix_new_inode(dir, mode, &error); 60 - if (inode) { 61 - minix_set_inode(inode, 0); 62 - mark_inode_dirty(inode); 63 - d_tmpfile(file, inode); 64 - } 65 - return finish_open_simple(file, error); 56 + struct inode *inode = minix_new_inode(dir, mode); 57 + 58 + if (IS_ERR(inode)) 59 + return finish_open_simple(file, PTR_ERR(inode)); 60 + minix_set_inode(inode, 0); 61 + mark_inode_dirty(inode); 62 + d_tmpfile(file, inode); 63 + return finish_open_simple(file, 0); 66 64 } 67 65 68 66 static int minix_create(struct mnt_idmap *idmap, struct inode *dir, ··· 72 74 static int minix_symlink(struct mnt_idmap *idmap, struct inode *dir, 73 75 struct dentry *dentry, const char *symname) 74 76 { 75 - int err = -ENAMETOOLONG; 76 77 int i = strlen(symname)+1; 77 78 struct inode * inode; 79 + int err; 78 80 79 81 if (i > dir->i_sb->s_blocksize) 80 - goto out; 82 + return -ENAMETOOLONG; 81 83 82 - inode = minix_new_inode(dir, S_IFLNK | 0777, &err); 83 - if (!inode) 84 - goto out; 84 + inode = minix_new_inode(dir, S_IFLNK | 0777); 85 + if (IS_ERR(inode)) 86 + return PTR_ERR(inode); 85 87 86 88 minix_set_inode(inode, 0); 87 89 err = page_symlink(inode, symname, i); 88 - if (err) 89 - goto out_fail; 90 - 91 - err = add_nondir(dentry, inode); 92 - out: 93 - return err; 94 - 95 - out_fail: 96 - inode_dec_link_count(inode); 97 - iput(inode); 98 - goto out; 90 + if (unlikely(err)) { 91 + inode_dec_link_count(inode); 92 + iput(inode); 93 + return err; 94 + } 95 + return add_nondir(dentry, inode); 99 96 } 100 97 101 98 static int minix_link(struct dentry * old_dentry, struct inode * dir, ··· 110 117 struct inode * inode; 111 118 int err; 112 119 120 + inode = minix_new_inode(dir, S_IFDIR | mode); 121 + if (IS_ERR(inode)) 122 + return PTR_ERR(inode); 123 + 113 124 inode_inc_link_count(dir); 114 - 115 - inode = minix_new_inode(dir, S_IFDIR | mode, &err); 116 - if (!inode) 117 - goto out_dir; 118 - 119 125 minix_set_inode(inode, 0); 120 - 121 126 inode_inc_link_count(inode); 122 127 123 128 err = minix_make_empty(inode, dir); ··· 134 143 inode_dec_link_count(inode); 135 144 inode_dec_link_count(inode); 136 145 iput(inode); 137 - out_dir: 138 146 inode_dec_link_count(dir); 139 147 goto out; 140 148 } 141 149 142 150 static int minix_unlink(struct inode * dir, struct dentry *dentry) 143 151 { 144 - int err = -ENOENT; 145 152 struct inode * inode = d_inode(dentry); 146 153 struct page * page; 147 154 struct minix_dir_entry * de; 155 + int err; 148 156 149 157 de = minix_find_entry(dentry, &page); 150 158 if (!de) 151 - goto end_unlink; 152 - 159 + return -ENOENT; 153 160 err = minix_delete_entry(de, page); 154 - if (err) 155 - goto end_unlink; 161 + kunmap(page); 162 + put_page(page); 156 163 164 + if (err) 165 + return err; 157 166 inode->i_ctime = dir->i_ctime; 158 167 inode_dec_link_count(inode); 159 - end_unlink: 160 - return err; 168 + return 0; 161 169 } 162 170 163 171 static int minix_rmdir(struct inode * dir, struct dentry *dentry) ··· 213 223 new_de = minix_find_entry(new_dentry, &new_page); 214 224 if (!new_de) 215 225 goto out_dir; 216 - minix_set_link(new_de, new_page, old_inode); 226 + err = minix_set_link(new_de, new_page, old_inode); 227 + kunmap(new_page); 228 + put_page(new_page); 229 + if (err) 230 + goto out_dir; 217 231 new_inode->i_ctime = current_time(new_inode); 218 232 if (dir_de) 219 233 drop_nlink(new_inode); ··· 230 236 inode_inc_link_count(new_dir); 231 237 } 232 238 233 - minix_delete_entry(old_de, old_page); 239 + err = minix_delete_entry(old_de, old_page); 240 + if (err) 241 + goto out_dir; 242 + 234 243 mark_inode_dirty(old_inode); 235 244 236 245 if (dir_de) { 237 - minix_set_link(dir_de, dir_page, new_dir); 238 - inode_dec_link_count(old_dir); 246 + err = minix_set_link(dir_de, dir_page, new_dir); 247 + if (!err) 248 + inode_dec_link_count(old_dir); 239 249 } 240 - return 0; 241 - 242 250 out_dir: 243 251 if (dir_de) { 244 252 kunmap(dir_page);