diff options
author | Vyacheslav Dubeyko <slava@dubeyko.com> | 2013-02-27 20:03:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-27 22:10:10 -0500 |
commit | 324ef39a8a4f693035d63527f16100ed27310ecc (patch) | |
tree | 1814515cf6139fe1b4ebae8d6641c9ec6293d396 /fs/hfsplus/dir.c | |
parent | 127e5f5ae51eff44c9bff673f24e8587caa4e29f (diff) |
hfsplus: add support of manipulation by attributes file
Add support of manipulation by attributes file.
Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com>
Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hfsplus/dir.c')
-rw-r--r-- | fs/hfsplus/dir.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 074e04589248..031c24e50521 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include "hfsplus_fs.h" | 16 | #include "hfsplus_fs.h" |
17 | #include "hfsplus_raw.h" | 17 | #include "hfsplus_raw.h" |
18 | #include "xattr.h" | ||
18 | 19 | ||
19 | static inline void hfsplus_instantiate(struct dentry *dentry, | 20 | static inline void hfsplus_instantiate(struct dentry *dentry, |
20 | struct inode *inode, u32 cnid) | 21 | struct inode *inode, u32 cnid) |
@@ -138,7 +139,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
138 | if (err) | 139 | if (err) |
139 | return err; | 140 | return err; |
140 | hfsplus_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); | 141 | hfsplus_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); |
141 | err = hfs_brec_find(&fd); | 142 | err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
142 | if (err) | 143 | if (err) |
143 | goto out; | 144 | goto out; |
144 | 145 | ||
@@ -421,6 +422,15 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, | |||
421 | if (res) | 422 | if (res) |
422 | goto out_err; | 423 | goto out_err; |
423 | 424 | ||
425 | res = hfsplus_init_inode_security(inode, dir, &dentry->d_name); | ||
426 | if (res == -EOPNOTSUPP) | ||
427 | res = 0; /* Operation is not supported. */ | ||
428 | else if (res) { | ||
429 | /* Try to delete anyway without error analysis. */ | ||
430 | hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); | ||
431 | goto out_err; | ||
432 | } | ||
433 | |||
424 | hfsplus_instantiate(dentry, inode, inode->i_ino); | 434 | hfsplus_instantiate(dentry, inode, inode->i_ino); |
425 | mark_inode_dirty(inode); | 435 | mark_inode_dirty(inode); |
426 | goto out; | 436 | goto out; |
@@ -450,15 +460,26 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, | |||
450 | init_special_inode(inode, mode, rdev); | 460 | init_special_inode(inode, mode, rdev); |
451 | 461 | ||
452 | res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); | 462 | res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); |
453 | if (res) { | 463 | if (res) |
454 | clear_nlink(inode); | 464 | goto failed_mknod; |
455 | hfsplus_delete_inode(inode); | 465 | |
456 | iput(inode); | 466 | res = hfsplus_init_inode_security(inode, dir, &dentry->d_name); |
457 | goto out; | 467 | if (res == -EOPNOTSUPP) |
468 | res = 0; /* Operation is not supported. */ | ||
469 | else if (res) { | ||
470 | /* Try to delete anyway without error analysis. */ | ||
471 | hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); | ||
472 | goto failed_mknod; | ||
458 | } | 473 | } |
459 | 474 | ||
460 | hfsplus_instantiate(dentry, inode, inode->i_ino); | 475 | hfsplus_instantiate(dentry, inode, inode->i_ino); |
461 | mark_inode_dirty(inode); | 476 | mark_inode_dirty(inode); |
477 | goto out; | ||
478 | |||
479 | failed_mknod: | ||
480 | clear_nlink(inode); | ||
481 | hfsplus_delete_inode(inode); | ||
482 | iput(inode); | ||
462 | out: | 483 | out: |
463 | mutex_unlock(&sbi->vh_mutex); | 484 | mutex_unlock(&sbi->vh_mutex); |
464 | return res; | 485 | return res; |
@@ -499,15 +520,19 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
499 | } | 520 | } |
500 | 521 | ||
501 | const struct inode_operations hfsplus_dir_inode_operations = { | 522 | const struct inode_operations hfsplus_dir_inode_operations = { |
502 | .lookup = hfsplus_lookup, | 523 | .lookup = hfsplus_lookup, |
503 | .create = hfsplus_create, | 524 | .create = hfsplus_create, |
504 | .link = hfsplus_link, | 525 | .link = hfsplus_link, |
505 | .unlink = hfsplus_unlink, | 526 | .unlink = hfsplus_unlink, |
506 | .mkdir = hfsplus_mkdir, | 527 | .mkdir = hfsplus_mkdir, |
507 | .rmdir = hfsplus_rmdir, | 528 | .rmdir = hfsplus_rmdir, |
508 | .symlink = hfsplus_symlink, | 529 | .symlink = hfsplus_symlink, |
509 | .mknod = hfsplus_mknod, | 530 | .mknod = hfsplus_mknod, |
510 | .rename = hfsplus_rename, | 531 | .rename = hfsplus_rename, |
532 | .setxattr = generic_setxattr, | ||
533 | .getxattr = generic_getxattr, | ||
534 | .listxattr = hfsplus_listxattr, | ||
535 | .removexattr = hfsplus_removexattr, | ||
511 | }; | 536 | }; |
512 | 537 | ||
513 | const struct file_operations hfsplus_dir_operations = { | 538 | const struct file_operations hfsplus_dir_operations = { |