diff options
Diffstat (limited to 'fs/nilfs2/namei.c')
-rw-r--r-- | fs/nilfs2/namei.c | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index ed02e886fa79..ad6ed2cf19b4 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -67,7 +67,7 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
67 | if (dentry->d_name.len > NILFS_NAME_LEN) | 67 | if (dentry->d_name.len > NILFS_NAME_LEN) |
68 | return ERR_PTR(-ENAMETOOLONG); | 68 | return ERR_PTR(-ENAMETOOLONG); |
69 | 69 | ||
70 | ino = nilfs_inode_by_name(dir, dentry); | 70 | ino = nilfs_inode_by_name(dir, &dentry->d_name); |
71 | inode = NULL; | 71 | inode = NULL; |
72 | if (ino) { | 72 | if (ino) { |
73 | inode = nilfs_iget(dir->i_sb, ino); | 73 | inode = nilfs_iget(dir->i_sb, ino); |
@@ -81,10 +81,7 @@ struct dentry *nilfs_get_parent(struct dentry *child) | |||
81 | { | 81 | { |
82 | unsigned long ino; | 82 | unsigned long ino; |
83 | struct inode *inode; | 83 | struct inode *inode; |
84 | struct dentry dotdot; | 84 | struct qstr dotdot = {.name = "..", .len = 2}; |
85 | |||
86 | dotdot.d_name.name = ".."; | ||
87 | dotdot.d_name.len = 2; | ||
88 | 85 | ||
89 | ino = nilfs_inode_by_name(child->d_inode, &dotdot); | 86 | ino = nilfs_inode_by_name(child->d_inode, &dotdot); |
90 | if (!ino) | 87 | if (!ino) |
@@ -120,7 +117,7 @@ static int nilfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
120 | inode->i_op = &nilfs_file_inode_operations; | 117 | inode->i_op = &nilfs_file_inode_operations; |
121 | inode->i_fop = &nilfs_file_operations; | 118 | inode->i_fop = &nilfs_file_operations; |
122 | inode->i_mapping->a_ops = &nilfs_aops; | 119 | inode->i_mapping->a_ops = &nilfs_aops; |
123 | mark_inode_dirty(inode); | 120 | nilfs_mark_inode_dirty(inode); |
124 | err = nilfs_add_nondir(dentry, inode); | 121 | err = nilfs_add_nondir(dentry, inode); |
125 | } | 122 | } |
126 | if (!err) | 123 | if (!err) |
@@ -148,7 +145,7 @@ nilfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
148 | err = PTR_ERR(inode); | 145 | err = PTR_ERR(inode); |
149 | if (!IS_ERR(inode)) { | 146 | if (!IS_ERR(inode)) { |
150 | init_special_inode(inode, inode->i_mode, rdev); | 147 | init_special_inode(inode, inode->i_mode, rdev); |
151 | mark_inode_dirty(inode); | 148 | nilfs_mark_inode_dirty(inode); |
152 | err = nilfs_add_nondir(dentry, inode); | 149 | err = nilfs_add_nondir(dentry, inode); |
153 | } | 150 | } |
154 | if (!err) | 151 | if (!err) |
@@ -188,7 +185,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry, | |||
188 | goto out_fail; | 185 | goto out_fail; |
189 | 186 | ||
190 | /* mark_inode_dirty(inode); */ | 187 | /* mark_inode_dirty(inode); */ |
191 | /* nilfs_new_inode() and page_symlink() do this */ | 188 | /* page_symlink() do this */ |
192 | 189 | ||
193 | err = nilfs_add_nondir(dentry, inode); | 190 | err = nilfs_add_nondir(dentry, inode); |
194 | out: | 191 | out: |
@@ -200,7 +197,8 @@ out: | |||
200 | return err; | 197 | return err; |
201 | 198 | ||
202 | out_fail: | 199 | out_fail: |
203 | inode_dec_link_count(inode); | 200 | drop_nlink(inode); |
201 | nilfs_mark_inode_dirty(inode); | ||
204 | iput(inode); | 202 | iput(inode); |
205 | goto out; | 203 | goto out; |
206 | } | 204 | } |
@@ -245,7 +243,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
245 | if (err) | 243 | if (err) |
246 | return err; | 244 | return err; |
247 | 245 | ||
248 | inode_inc_link_count(dir); | 246 | inc_nlink(dir); |
249 | 247 | ||
250 | inode = nilfs_new_inode(dir, S_IFDIR | mode); | 248 | inode = nilfs_new_inode(dir, S_IFDIR | mode); |
251 | err = PTR_ERR(inode); | 249 | err = PTR_ERR(inode); |
@@ -256,7 +254,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
256 | inode->i_fop = &nilfs_dir_operations; | 254 | inode->i_fop = &nilfs_dir_operations; |
257 | inode->i_mapping->a_ops = &nilfs_aops; | 255 | inode->i_mapping->a_ops = &nilfs_aops; |
258 | 256 | ||
259 | inode_inc_link_count(inode); | 257 | inc_nlink(inode); |
260 | 258 | ||
261 | err = nilfs_make_empty(inode, dir); | 259 | err = nilfs_make_empty(inode, dir); |
262 | if (err) | 260 | if (err) |
@@ -266,6 +264,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
266 | if (err) | 264 | if (err) |
267 | goto out_fail; | 265 | goto out_fail; |
268 | 266 | ||
267 | nilfs_mark_inode_dirty(inode); | ||
269 | d_instantiate(dentry, inode); | 268 | d_instantiate(dentry, inode); |
270 | out: | 269 | out: |
271 | if (!err) | 270 | if (!err) |
@@ -276,28 +275,25 @@ out: | |||
276 | return err; | 275 | return err; |
277 | 276 | ||
278 | out_fail: | 277 | out_fail: |
279 | inode_dec_link_count(inode); | 278 | drop_nlink(inode); |
280 | inode_dec_link_count(inode); | 279 | drop_nlink(inode); |
280 | nilfs_mark_inode_dirty(inode); | ||
281 | iput(inode); | 281 | iput(inode); |
282 | out_dir: | 282 | out_dir: |
283 | inode_dec_link_count(dir); | 283 | drop_nlink(dir); |
284 | nilfs_mark_inode_dirty(dir); | ||
284 | goto out; | 285 | goto out; |
285 | } | 286 | } |
286 | 287 | ||
287 | static int nilfs_unlink(struct inode *dir, struct dentry *dentry) | 288 | static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry) |
288 | { | 289 | { |
289 | struct inode *inode; | 290 | struct inode *inode; |
290 | struct nilfs_dir_entry *de; | 291 | struct nilfs_dir_entry *de; |
291 | struct page *page; | 292 | struct page *page; |
292 | struct nilfs_transaction_info ti; | ||
293 | int err; | 293 | int err; |
294 | 294 | ||
295 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); | ||
296 | if (err) | ||
297 | return err; | ||
298 | |||
299 | err = -ENOENT; | 295 | err = -ENOENT; |
300 | de = nilfs_find_entry(dir, dentry, &page); | 296 | de = nilfs_find_entry(dir, &dentry->d_name, &page); |
301 | if (!de) | 297 | if (!de) |
302 | goto out; | 298 | goto out; |
303 | 299 | ||
@@ -317,12 +313,28 @@ static int nilfs_unlink(struct inode *dir, struct dentry *dentry) | |||
317 | goto out; | 313 | goto out; |
318 | 314 | ||
319 | inode->i_ctime = dir->i_ctime; | 315 | inode->i_ctime = dir->i_ctime; |
320 | inode_dec_link_count(inode); | 316 | drop_nlink(inode); |
321 | err = 0; | 317 | err = 0; |
322 | out: | 318 | out: |
323 | if (!err) | 319 | return err; |
320 | } | ||
321 | |||
322 | static int nilfs_unlink(struct inode *dir, struct dentry *dentry) | ||
323 | { | ||
324 | struct nilfs_transaction_info ti; | ||
325 | int err; | ||
326 | |||
327 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); | ||
328 | if (err) | ||
329 | return err; | ||
330 | |||
331 | err = nilfs_do_unlink(dir, dentry); | ||
332 | |||
333 | if (!err) { | ||
334 | nilfs_mark_inode_dirty(dir); | ||
335 | nilfs_mark_inode_dirty(dentry->d_inode); | ||
324 | err = nilfs_transaction_commit(dir->i_sb); | 336 | err = nilfs_transaction_commit(dir->i_sb); |
325 | else | 337 | } else |
326 | nilfs_transaction_abort(dir->i_sb); | 338 | nilfs_transaction_abort(dir->i_sb); |
327 | 339 | ||
328 | return err; | 340 | return err; |
@@ -340,11 +352,13 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
340 | 352 | ||
341 | err = -ENOTEMPTY; | 353 | err = -ENOTEMPTY; |
342 | if (nilfs_empty_dir(inode)) { | 354 | if (nilfs_empty_dir(inode)) { |
343 | err = nilfs_unlink(dir, dentry); | 355 | err = nilfs_do_unlink(dir, dentry); |
344 | if (!err) { | 356 | if (!err) { |
345 | inode->i_size = 0; | 357 | inode->i_size = 0; |
346 | inode_dec_link_count(inode); | 358 | drop_nlink(inode); |
347 | inode_dec_link_count(dir); | 359 | nilfs_mark_inode_dirty(inode); |
360 | drop_nlink(dir); | ||
361 | nilfs_mark_inode_dirty(dir); | ||
348 | } | 362 | } |
349 | } | 363 | } |
350 | if (!err) | 364 | if (!err) |
@@ -372,7 +386,7 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
372 | return err; | 386 | return err; |
373 | 387 | ||
374 | err = -ENOENT; | 388 | err = -ENOENT; |
375 | old_de = nilfs_find_entry(old_dir, old_dentry, &old_page); | 389 | old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
376 | if (!old_de) | 390 | if (!old_de) |
377 | goto out; | 391 | goto out; |
378 | 392 | ||
@@ -392,45 +406,51 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
392 | goto out_dir; | 406 | goto out_dir; |
393 | 407 | ||
394 | err = -ENOENT; | 408 | err = -ENOENT; |
395 | new_de = nilfs_find_entry(new_dir, new_dentry, &new_page); | 409 | new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page); |
396 | if (!new_de) | 410 | if (!new_de) |
397 | goto out_dir; | 411 | goto out_dir; |
398 | inode_inc_link_count(old_inode); | 412 | inc_nlink(old_inode); |
399 | nilfs_set_link(new_dir, new_de, new_page, old_inode); | 413 | nilfs_set_link(new_dir, new_de, new_page, old_inode); |
414 | nilfs_mark_inode_dirty(new_dir); | ||
400 | new_inode->i_ctime = CURRENT_TIME; | 415 | new_inode->i_ctime = CURRENT_TIME; |
401 | if (dir_de) | 416 | if (dir_de) |
402 | drop_nlink(new_inode); | 417 | drop_nlink(new_inode); |
403 | inode_dec_link_count(new_inode); | 418 | drop_nlink(new_inode); |
419 | nilfs_mark_inode_dirty(new_inode); | ||
404 | } else { | 420 | } else { |
405 | if (dir_de) { | 421 | if (dir_de) { |
406 | err = -EMLINK; | 422 | err = -EMLINK; |
407 | if (new_dir->i_nlink >= NILFS_LINK_MAX) | 423 | if (new_dir->i_nlink >= NILFS_LINK_MAX) |
408 | goto out_dir; | 424 | goto out_dir; |
409 | } | 425 | } |
410 | inode_inc_link_count(old_inode); | 426 | inc_nlink(old_inode); |
411 | err = nilfs_add_link(new_dentry, old_inode); | 427 | err = nilfs_add_link(new_dentry, old_inode); |
412 | if (err) { | 428 | if (err) { |
413 | inode_dec_link_count(old_inode); | 429 | drop_nlink(old_inode); |
430 | nilfs_mark_inode_dirty(old_inode); | ||
414 | goto out_dir; | 431 | goto out_dir; |
415 | } | 432 | } |
416 | if (dir_de) | 433 | if (dir_de) { |
417 | inode_inc_link_count(new_dir); | 434 | inc_nlink(new_dir); |
435 | nilfs_mark_inode_dirty(new_dir); | ||
436 | } | ||
418 | } | 437 | } |
419 | 438 | ||
420 | /* | 439 | /* |
421 | * Like most other Unix systems, set the ctime for inodes on a | 440 | * Like most other Unix systems, set the ctime for inodes on a |
422 | * rename. | 441 | * rename. |
423 | * inode_dec_link_count() will mark the inode dirty. | ||
424 | */ | 442 | */ |
425 | old_inode->i_ctime = CURRENT_TIME; | 443 | old_inode->i_ctime = CURRENT_TIME; |
426 | 444 | ||
427 | nilfs_delete_entry(old_de, old_page); | 445 | nilfs_delete_entry(old_de, old_page); |
428 | inode_dec_link_count(old_inode); | 446 | drop_nlink(old_inode); |
429 | 447 | ||
430 | if (dir_de) { | 448 | if (dir_de) { |
431 | nilfs_set_link(old_inode, dir_de, dir_page, new_dir); | 449 | nilfs_set_link(old_inode, dir_de, dir_page, new_dir); |
432 | inode_dec_link_count(old_dir); | 450 | drop_nlink(old_dir); |
433 | } | 451 | } |
452 | nilfs_mark_inode_dirty(old_dir); | ||
453 | nilfs_mark_inode_dirty(old_inode); | ||
434 | 454 | ||
435 | err = nilfs_transaction_commit(old_dir->i_sb); | 455 | err = nilfs_transaction_commit(old_dir->i_sb); |
436 | return err; | 456 | return err; |