aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-06-14 06:17:15 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2013-06-14 06:17:15 -0400
commit6d4ade986f9c8df31e68fd30643997f79cc5a5f8 (patch)
treef0758a7a9b008d0bd3665234a5074e3cf6f4d455 /fs/gfs2
parent5a00f3cc978be45b9d2597851bedaa40630bc597 (diff)
GFS2: Add atomic_open support
I've restricted atomic_open to only operate on regular files, although I still don't understand why atomic_open should not be possible also for directories on GFS2. That can always be added in later though, if it makes sense. The ->atomic_open function can be passed negative dentries, which in most cases means either ENOENT (->lookup) or a call to d_instantiate (->create). In the GFS2 case though, we need to actually perform the look up, since we do not know whether there has been a new inode created on another node. The look up calls d_splice_alias which then tries to rehash the dentry - so the solution here is to simply check for that in d_splice_alias. The same issue is likely to affect any other cluster filesystem implementing ->atomic_open Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: "J. Bruce Fields" <bfields fieldses org> Cc: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/file.c69
-rw-r--r--fs/gfs2/inode.c125
-rw-r--r--fs/gfs2/inode.h1
3 files changed, 146 insertions, 49 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index ad0dc38d87ab..4ed6a03e565b 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -538,21 +538,30 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
538} 538}
539 539
540/** 540/**
541 * gfs2_open - open a file 541 * gfs2_open_common - This is common to open and atomic_open
542 * @inode: the inode to open 542 * @inode: The inode being opened
543 * @file: the struct file for this opening 543 * @file: The file being opened
544 * 544 *
545 * Returns: errno 545 * This maybe called under a glock or not depending upon how it has
546 * been called. We must always be called under a glock for regular
547 * files, however. For other file types, it does not matter whether
548 * we hold the glock or not.
549 *
550 * Returns: Error code or 0 for success
546 */ 551 */
547 552
548static int gfs2_open(struct inode *inode, struct file *file) 553int gfs2_open_common(struct inode *inode, struct file *file)
549{ 554{
550 struct gfs2_inode *ip = GFS2_I(inode);
551 struct gfs2_holder i_gh;
552 struct gfs2_file *fp; 555 struct gfs2_file *fp;
553 int error; 556 int ret;
554 557
555 fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL); 558 if (S_ISREG(inode->i_mode)) {
559 ret = generic_file_open(inode, file);
560 if (ret)
561 return ret;
562 }
563
564 fp = kzalloc(sizeof(struct gfs2_file), GFP_NOFS);
556 if (!fp) 565 if (!fp)
557 return -ENOMEM; 566 return -ENOMEM;
558 567
@@ -560,29 +569,43 @@ static int gfs2_open(struct inode *inode, struct file *file)
560 569
561 gfs2_assert_warn(GFS2_SB(inode), !file->private_data); 570 gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
562 file->private_data = fp; 571 file->private_data = fp;
572 return 0;
573}
574
575/**
576 * gfs2_open - open a file
577 * @inode: the inode to open
578 * @file: the struct file for this opening
579 *
580 * After atomic_open, this function is only used for opening files
581 * which are already cached. We must still get the glock for regular
582 * files to ensure that we have the file size uptodate for the large
583 * file check which is in the common code. That is only an issue for
584 * regular files though.
585 *
586 * Returns: errno
587 */
588
589static int gfs2_open(struct inode *inode, struct file *file)
590{
591 struct gfs2_inode *ip = GFS2_I(inode);
592 struct gfs2_holder i_gh;
593 int error;
594 bool need_unlock = false;
563 595
564 if (S_ISREG(ip->i_inode.i_mode)) { 596 if (S_ISREG(ip->i_inode.i_mode)) {
565 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, 597 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
566 &i_gh); 598 &i_gh);
567 if (error) 599 if (error)
568 goto fail; 600 return error;
601 need_unlock = true;
602 }
569 603
570 if (!(file->f_flags & O_LARGEFILE) && 604 error = gfs2_open_common(inode, file);
571 i_size_read(inode) > MAX_NON_LFS) {
572 error = -EOVERFLOW;
573 goto fail_gunlock;
574 }
575 605
606 if (need_unlock)
576 gfs2_glock_dq_uninit(&i_gh); 607 gfs2_glock_dq_uninit(&i_gh);
577 }
578
579 return 0;
580 608
581fail_gunlock:
582 gfs2_glock_dq_uninit(&i_gh);
583fail:
584 file->private_data = NULL;
585 kfree(fp);
586 return error; 609 return error;
587} 610}
588 611
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index ede16ae784e2..bbb2715171cd 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -535,6 +535,7 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
535 * gfs2_create_inode - Create a new inode 535 * gfs2_create_inode - Create a new inode
536 * @dir: The parent directory 536 * @dir: The parent directory
537 * @dentry: The new dentry 537 * @dentry: The new dentry
538 * @file: If non-NULL, the file which is being opened
538 * @mode: The permissions on the new inode 539 * @mode: The permissions on the new inode
539 * @dev: For device nodes, this is the device number 540 * @dev: For device nodes, this is the device number
540 * @symname: For symlinks, this is the link destination 541 * @symname: For symlinks, this is the link destination
@@ -544,8 +545,9 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
544 */ 545 */
545 546
546static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, 547static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
548 struct file *file,
547 umode_t mode, dev_t dev, const char *symname, 549 umode_t mode, dev_t dev, const char *symname,
548 unsigned int size, int excl) 550 unsigned int size, int excl, int *opened)
549{ 551{
550 const struct qstr *name = &dentry->d_name; 552 const struct qstr *name = &dentry->d_name;
551 struct gfs2_holder ghs[2]; 553 struct gfs2_holder ghs[2];
@@ -553,6 +555,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
553 struct gfs2_inode *dip = GFS2_I(dir), *ip; 555 struct gfs2_inode *dip = GFS2_I(dir), *ip;
554 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 556 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
555 struct gfs2_glock *io_gl; 557 struct gfs2_glock *io_gl;
558 struct dentry *d;
556 int error; 559 int error;
557 u32 aflags = 0; 560 u32 aflags = 0;
558 int arq; 561 int arq;
@@ -579,9 +582,20 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
579 inode = gfs2_dir_search(dir, &dentry->d_name, !S_ISREG(mode) || excl); 582 inode = gfs2_dir_search(dir, &dentry->d_name, !S_ISREG(mode) || excl);
580 error = PTR_ERR(inode); 583 error = PTR_ERR(inode);
581 if (!IS_ERR(inode)) { 584 if (!IS_ERR(inode)) {
585 d = d_splice_alias(inode, dentry);
586 error = 0;
587 if (file && !IS_ERR(d)) {
588 if (d == NULL)
589 d = dentry;
590 if (S_ISREG(inode->i_mode))
591 error = finish_open(file, d, gfs2_open_common, opened);
592 else
593 error = finish_no_open(file, d);
594 }
582 gfs2_glock_dq_uninit(ghs); 595 gfs2_glock_dq_uninit(ghs);
583 d_instantiate(dentry, inode); 596 if (IS_ERR(d))
584 return 0; 597 return PTR_RET(d);
598 return error;
585 } else if (error != -ENOENT) { 599 } else if (error != -ENOENT) {
586 goto fail_gunlock; 600 goto fail_gunlock;
587 } 601 }
@@ -679,10 +693,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
679 goto fail_gunlock3; 693 goto fail_gunlock3;
680 694
681 mark_inode_dirty(inode); 695 mark_inode_dirty(inode);
696 d_instantiate(dentry, inode);
697 if (file)
698 error = finish_open(file, dentry, gfs2_open_common, opened);
682 gfs2_glock_dq_uninit(ghs); 699 gfs2_glock_dq_uninit(ghs);
683 gfs2_glock_dq_uninit(ghs + 1); 700 gfs2_glock_dq_uninit(ghs + 1);
684 d_instantiate(dentry, inode); 701 return error;
685 return 0;
686 702
687fail_gunlock3: 703fail_gunlock3:
688 gfs2_glock_dq_uninit(ghs + 1); 704 gfs2_glock_dq_uninit(ghs + 1);
@@ -722,36 +738,56 @@ fail:
722static int gfs2_create(struct inode *dir, struct dentry *dentry, 738static int gfs2_create(struct inode *dir, struct dentry *dentry,
723 umode_t mode, bool excl) 739 umode_t mode, bool excl)
724{ 740{
725 return gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0, excl); 741 return gfs2_create_inode(dir, dentry, NULL, S_IFREG | mode, 0, NULL, 0, excl, NULL);
726} 742}
727 743
728/** 744/**
729 * gfs2_lookup - Look up a filename in a directory and return its inode 745 * __gfs2_lookup - Look up a filename in a directory and return its inode
730 * @dir: The directory inode 746 * @dir: The directory inode
731 * @dentry: The dentry of the new inode 747 * @dentry: The dentry of the new inode
732 * @nd: passed from Linux VFS, ignored by us 748 * @file: File to be opened
749 * @opened: atomic_open flags
733 * 750 *
734 * Called by the VFS layer. Lock dir and call gfs2_lookupi()
735 * 751 *
736 * Returns: errno 752 * Returns: errno
737 */ 753 */
738 754
739static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, 755static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry,
740 unsigned int flags) 756 struct file *file, int *opened)
741{ 757{
742 struct inode *inode = gfs2_lookupi(dir, &dentry->d_name, 0); 758 struct inode *inode;
743 if (inode && !IS_ERR(inode)) { 759 struct dentry *d;
744 struct gfs2_glock *gl = GFS2_I(inode)->i_gl; 760 struct gfs2_holder gh;
745 struct gfs2_holder gh; 761 struct gfs2_glock *gl;
746 int error; 762 int error;
747 error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); 763
748 if (error) { 764 inode = gfs2_lookupi(dir, &dentry->d_name, 0);
749 iput(inode); 765 if (!inode)
750 return ERR_PTR(error); 766 return NULL;
751 } 767 if (IS_ERR(inode))
752 gfs2_glock_dq_uninit(&gh); 768 return ERR_CAST(inode);
769
770 gl = GFS2_I(inode)->i_gl;
771 error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
772 if (error) {
773 iput(inode);
774 return ERR_PTR(error);
753 } 775 }
754 return d_splice_alias(inode, dentry); 776
777 d = d_splice_alias(inode, dentry);
778 if (file && S_ISREG(inode->i_mode))
779 error = finish_open(file, dentry, gfs2_open_common, opened);
780
781 gfs2_glock_dq_uninit(&gh);
782 if (error)
783 return ERR_PTR(error);
784 return d;
785}
786
787static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
788 unsigned flags)
789{
790 return __gfs2_lookup(dir, dentry, NULL, NULL);
755} 791}
756 792
757/** 793/**
@@ -1069,7 +1105,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
1069 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) 1105 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
1070 return -ENAMETOOLONG; 1106 return -ENAMETOOLONG;
1071 1107
1072 return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size, 0); 1108 return gfs2_create_inode(dir, dentry, NULL, S_IFLNK | S_IRWXUGO, 0, symname, size, 0, NULL);
1073} 1109}
1074 1110
1075/** 1111/**
@@ -1085,7 +1121,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1085{ 1121{
1086 struct gfs2_sbd *sdp = GFS2_SB(dir); 1122 struct gfs2_sbd *sdp = GFS2_SB(dir);
1087 unsigned dsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); 1123 unsigned dsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode);
1088 return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, dsize, 0); 1124 return gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0, NULL);
1089} 1125}
1090 1126
1091/** 1127/**
@@ -1100,7 +1136,43 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1100static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, 1136static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
1101 dev_t dev) 1137 dev_t dev)
1102{ 1138{
1103 return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0, 0); 1139 return gfs2_create_inode(dir, dentry, NULL, mode, dev, NULL, 0, 0, NULL);
1140}
1141
1142/**
1143 * gfs2_atomic_open - Atomically open a file
1144 * @dir: The directory
1145 * @dentry: The proposed new entry
1146 * @file: The proposed new struct file
1147 * @flags: open flags
1148 * @mode: File mode
1149 * @opened: Flag to say whether the file has been opened or not
1150 *
1151 * Returns: error code or 0 for success
1152 */
1153
1154static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry,
1155 struct file *file, unsigned flags,
1156 umode_t mode, int *opened)
1157{
1158 struct dentry *d;
1159 bool excl = !!(flags & O_EXCL);
1160
1161 d = __gfs2_lookup(dir, dentry, file, opened);
1162 if (IS_ERR(d))
1163 return PTR_ERR(d);
1164 if (d == NULL)
1165 d = dentry;
1166 if (d->d_inode) {
1167 if (!(*opened & FILE_OPENED))
1168 return finish_no_open(file, d);
1169 return 0;
1170 }
1171
1172 if (!(flags & O_CREAT))
1173 return -ENOENT;
1174
1175 return gfs2_create_inode(dir, dentry, file, S_IFREG | mode, 0, NULL, 0, excl, opened);
1104} 1176}
1105 1177
1106/* 1178/*
@@ -1780,6 +1852,7 @@ const struct inode_operations gfs2_dir_iops = {
1780 .removexattr = gfs2_removexattr, 1852 .removexattr = gfs2_removexattr,
1781 .fiemap = gfs2_fiemap, 1853 .fiemap = gfs2_fiemap,
1782 .get_acl = gfs2_get_acl, 1854 .get_acl = gfs2_get_acl,
1855 .atomic_open = gfs2_atomic_open,
1783}; 1856};
1784 1857
1785const struct inode_operations gfs2_symlink_iops = { 1858const struct inode_operations gfs2_symlink_iops = {
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index c53c7477f6da..ba4d9492d422 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -109,6 +109,7 @@ extern int gfs2_permission(struct inode *inode, int mask);
109extern int gfs2_setattr_simple(struct inode *inode, struct iattr *attr); 109extern int gfs2_setattr_simple(struct inode *inode, struct iattr *attr);
110extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); 110extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
111extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); 111extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);
112extern int gfs2_open_common(struct inode *inode, struct file *file);
112 113
113extern const struct inode_operations gfs2_file_iops; 114extern const struct inode_operations gfs2_file_iops;
114extern const struct inode_operations gfs2_dir_iops; 115extern const struct inode_operations gfs2_dir_iops;