2 * Copyright (C) International Business Machines Corp., 2000-2002
3 * Portions Copyright (C) Christoph Hellwig, 2001-2002
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/posix_acl.h>
23 #include <linux/quotaops.h>
24 #include "jfs_incore.h"
25 #include "jfs_inode.h"
27 #include "jfs_txnmgr.h"
28 #include "jfs_xattr.h"
30 #include "jfs_debug.h"
32 int jfs_fsync(struct file
*file
, loff_t start
, loff_t end
, int datasync
)
34 struct inode
*inode
= file
->f_mapping
->host
;
37 rc
= filemap_write_and_wait_range(inode
->i_mapping
, start
, end
);
42 if (!(inode
->i_state
& I_DIRTY_ALL
) ||
43 (datasync
&& !(inode
->i_state
& I_DIRTY_DATASYNC
))) {
44 /* Make sure committed changes hit the disk */
45 jfs_flush_journal(JFS_SBI(inode
->i_sb
)->log
, 1);
50 rc
|= jfs_commit_inode(inode
, 1);
56 static int jfs_open(struct inode
*inode
, struct file
*file
)
60 if ((rc
= dquot_file_open(inode
, file
)))
64 * We attempt to allow only one "active" file open per aggregate
65 * group. Otherwise, appending to files in parallel can cause
66 * fragmentation within the files.
68 * If the file is empty, it was probably just created and going
69 * to be written to. If it has a size, we'll hold off until the
70 * file is actually grown.
72 if (S_ISREG(inode
->i_mode
) && file
->f_mode
& FMODE_WRITE
&&
73 (inode
->i_size
== 0)) {
74 struct jfs_inode_info
*ji
= JFS_IP(inode
);
75 spin_lock_irq(&ji
->ag_lock
);
76 if (ji
->active_ag
== -1) {
77 struct jfs_sb_info
*jfs_sb
= JFS_SBI(inode
->i_sb
);
78 ji
->active_ag
= BLKTOAG(addressPXD(&ji
->ixpxd
), jfs_sb
);
79 atomic_inc(&jfs_sb
->bmap
->db_active
[ji
->active_ag
]);
81 spin_unlock_irq(&ji
->ag_lock
);
86 static int jfs_release(struct inode
*inode
, struct file
*file
)
88 struct jfs_inode_info
*ji
= JFS_IP(inode
);
90 spin_lock_irq(&ji
->ag_lock
);
91 if (ji
->active_ag
!= -1) {
92 struct bmap
*bmap
= JFS_SBI(inode
->i_sb
)->bmap
;
93 atomic_dec(&bmap
->db_active
[ji
->active_ag
]);
96 spin_unlock_irq(&ji
->ag_lock
);
101 int jfs_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
103 struct inode
*inode
= d_inode(dentry
);
106 rc
= setattr_prepare(dentry
, iattr
);
110 if (is_quota_modification(inode
, iattr
)) {
111 rc
= dquot_initialize(inode
);
115 if ((iattr
->ia_valid
& ATTR_UID
&& !uid_eq(iattr
->ia_uid
, inode
->i_uid
)) ||
116 (iattr
->ia_valid
& ATTR_GID
&& !gid_eq(iattr
->ia_gid
, inode
->i_gid
))) {
117 rc
= dquot_transfer(inode
, iattr
);
122 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
123 iattr
->ia_size
!= i_size_read(inode
)) {
124 inode_dio_wait(inode
);
126 rc
= inode_newsize_ok(inode
, iattr
->ia_size
);
130 truncate_setsize(inode
, iattr
->ia_size
);
134 setattr_copy(inode
, iattr
);
135 mark_inode_dirty(inode
);
137 if (iattr
->ia_valid
& ATTR_MODE
)
138 rc
= posix_acl_chmod(inode
, inode
->i_mode
);
142 const struct inode_operations jfs_file_inode_operations
= {
143 .listxattr
= jfs_listxattr
,
144 .setattr
= jfs_setattr
,
145 #ifdef CONFIG_JFS_POSIX_ACL
146 .get_acl
= jfs_get_acl
,
147 .set_acl
= jfs_set_acl
,
151 const struct file_operations jfs_file_operations
= {
153 .llseek
= generic_file_llseek
,
154 .read_iter
= generic_file_read_iter
,
155 .write_iter
= generic_file_write_iter
,
156 .mmap
= generic_file_mmap
,
157 .splice_read
= generic_file_splice_read
,
158 .splice_write
= iter_file_splice_write
,
160 .release
= jfs_release
,
161 .unlocked_ioctl
= jfs_ioctl
,
163 .compat_ioctl
= jfs_compat_ioctl
,