2005-04-17 02:20:36 +04:00
/*
2005-05-05 00:29:35 +04:00
* Copyright ( C ) International Business Machines Corp . , 2000 - 2002
* Portions Copyright ( C ) Christoph Hellwig , 2001 - 2002
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2006-10-02 18:55:27 +04:00
* the Free Software Foundation ; either version 2 of the License , or
2005-04-17 02:20:36 +04:00
* ( at your option ) any later version .
2006-10-02 18:55:27 +04:00
*
2005-04-17 02:20:36 +04:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See
* the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2006-10-02 18:55:27 +04:00
* along with this program ; if not , write to the Free Software
2005-04-17 02:20:36 +04:00
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
2010-06-04 13:30:02 +04:00
# include <linux/mm.h>
2005-04-17 02:20:36 +04:00
# include <linux/fs.h>
2013-12-20 17:16:51 +04:00
# include <linux/posix_acl.h>
2010-03-03 17:05:02 +03:00
# include <linux/quotaops.h>
2005-04-17 02:20:36 +04:00
# include "jfs_incore.h"
2005-05-05 00:29:35 +04:00
# include "jfs_inode.h"
2005-04-17 02:20:36 +04:00
# include "jfs_dmap.h"
# include "jfs_txnmgr.h"
# include "jfs_xattr.h"
# include "jfs_acl.h"
# include "jfs_debug.h"
2011-07-17 04:44:56 +04:00
int jfs_fsync ( struct file * file , loff_t start , loff_t end , int datasync )
2005-04-17 02:20:36 +04:00
{
2010-05-26 19:53:25 +04:00
struct inode * inode = file - > f_mapping - > host ;
2005-04-17 02:20:36 +04:00
int rc = 0 ;
2011-07-17 04:44:56 +04:00
rc = filemap_write_and_wait_range ( inode - > i_mapping , start , end ) ;
if ( rc )
return rc ;
2016-01-22 23:40:57 +03:00
inode_lock ( inode ) ;
2015-02-02 08:37:00 +03:00
if ( ! ( inode - > i_state & I_DIRTY_ALL ) | |
2005-04-17 02:20:36 +04:00
( datasync & & ! ( inode - > i_state & I_DIRTY_DATASYNC ) ) ) {
/* Make sure committed changes hit the disk */
jfs_flush_journal ( JFS_SBI ( inode - > i_sb ) - > log , 1 ) ;
2016-01-22 23:40:57 +03:00
inode_unlock ( inode ) ;
2005-04-17 02:20:36 +04:00
return rc ;
}
rc | = jfs_commit_inode ( inode , 1 ) ;
2016-01-22 23:40:57 +03:00
inode_unlock ( inode ) ;
2005-04-17 02:20:36 +04:00
return rc ? - EIO : 0 ;
}
static int jfs_open ( struct inode * inode , struct file * file )
{
int rc ;
2010-03-03 17:05:06 +03:00
if ( ( rc = dquot_file_open ( inode , file ) ) )
2005-04-17 02:20:36 +04:00
return rc ;
/*
* We attempt to allow only one " active " file open per aggregate
* group . Otherwise , appending to files in parallel can cause
* fragmentation within the files .
*
* If the file is empty , it was probably just created and going
* to be written to . If it has a size , we ' ll hold off until the
* file is actually grown .
*/
if ( S_ISREG ( inode - > i_mode ) & & file - > f_mode & FMODE_WRITE & &
( inode - > i_size = = 0 ) ) {
struct jfs_inode_info * ji = JFS_IP ( inode ) ;
spin_lock_irq ( & ji - > ag_lock ) ;
if ( ji - > active_ag = = - 1 ) {
2011-06-20 19:53:46 +04:00
struct jfs_sb_info * jfs_sb = JFS_SBI ( inode - > i_sb ) ;
ji - > active_ag = BLKTOAG ( addressPXD ( & ji - > ixpxd ) , jfs_sb ) ;
2015-05-31 12:53:28 +03:00
atomic_inc ( & jfs_sb - > bmap - > db_active [ ji - > active_ag ] ) ;
2005-04-17 02:20:36 +04:00
}
spin_unlock_irq ( & ji - > ag_lock ) ;
}
return 0 ;
}
static int jfs_release ( struct inode * inode , struct file * file )
{
struct jfs_inode_info * ji = JFS_IP ( inode ) ;
spin_lock_irq ( & ji - > ag_lock ) ;
if ( ji - > active_ag ! = - 1 ) {
struct bmap * bmap = JFS_SBI ( inode - > i_sb ) - > bmap ;
atomic_dec ( & bmap - > db_active [ ji - > active_ag ] ) ;
ji - > active_ag = - 1 ;
}
spin_unlock_irq ( & ji - > ag_lock ) ;
return 0 ;
}
2010-03-03 17:05:02 +03:00
int jfs_setattr ( struct dentry * dentry , struct iattr * iattr )
{
2015-03-18 01:25:59 +03:00
struct inode * inode = d_inode ( dentry ) ;
2010-03-03 17:05:02 +03:00
int rc ;
rc = inode_change_ok ( inode , iattr ) ;
if ( rc )
return rc ;
2015-07-15 21:53:19 +03:00
if ( is_quota_modification ( inode , iattr ) ) {
rc = dquot_initialize ( inode ) ;
if ( rc )
return rc ;
}
2012-02-10 23:40:34 +04:00
if ( ( iattr - > ia_valid & ATTR_UID & & ! uid_eq ( iattr - > ia_uid , inode - > i_uid ) ) | |
( iattr - > ia_valid & ATTR_GID & & ! gid_eq ( iattr - > ia_gid , inode - > i_gid ) ) ) {
2010-03-03 17:05:03 +03:00
rc = dquot_transfer ( inode , iattr ) ;
if ( rc )
return rc ;
2010-03-03 17:05:02 +03:00
}
2010-06-04 13:30:02 +04:00
if ( ( iattr - > ia_valid & ATTR_SIZE ) & &
iattr - > ia_size ! = i_size_read ( inode ) ) {
2011-06-24 22:29:45 +04:00
inode_dio_wait ( inode ) ;
2012-12-15 14:54:25 +04:00
rc = inode_newsize_ok ( inode , iattr - > ia_size ) ;
2010-06-04 13:30:02 +04:00
if ( rc )
return rc ;
2012-12-15 14:54:25 +04:00
truncate_setsize ( inode , iattr - > ia_size ) ;
jfs_truncate ( inode ) ;
2010-06-04 13:30:02 +04:00
}
2010-03-03 17:05:02 +03:00
2010-06-04 13:30:02 +04:00
setattr_copy ( inode , iattr ) ;
mark_inode_dirty ( inode ) ;
2010-03-03 17:05:02 +03:00
2010-06-04 13:30:02 +04:00
if ( iattr - > ia_valid & ATTR_MODE )
2013-12-20 17:16:51 +04:00
rc = posix_acl_chmod ( inode , inode - > i_mode ) ;
2010-03-03 17:05:02 +03:00
return rc ;
}
2007-02-12 11:55:39 +03:00
const struct inode_operations jfs_file_inode_operations = {
2016-04-22 15:43:49 +03:00
. setxattr = generic_setxattr ,
. getxattr = generic_getxattr ,
2005-04-17 02:20:36 +04:00
. listxattr = jfs_listxattr ,
2016-04-22 15:43:49 +03:00
. removexattr = generic_removexattr ,
2005-04-17 02:20:36 +04:00
. setattr = jfs_setattr ,
2010-03-03 17:05:02 +03:00
# ifdef CONFIG_JFS_POSIX_ACL
2011-07-23 19:37:31 +04:00
. get_acl = jfs_get_acl ,
2013-12-20 17:16:51 +04:00
. set_acl = jfs_set_acl ,
2005-04-17 02:20:36 +04:00
# endif
} ;
2006-03-28 13:56:42 +04:00
const struct file_operations jfs_file_operations = {
2005-04-17 02:20:36 +04:00
. open = jfs_open ,
. llseek = generic_file_llseek ,
2014-04-02 22:33:16 +04:00
. read_iter = generic_file_read_iter ,
2014-04-03 11:17:43 +04:00
. write_iter = generic_file_write_iter ,
2005-04-17 02:20:36 +04:00
. mmap = generic_file_mmap ,
2006-10-30 20:47:02 +03:00
. splice_read = generic_file_splice_read ,
2014-04-05 12:27:08 +04:00
. splice_write = iter_file_splice_write ,
2005-04-17 02:20:36 +04:00
. fsync = jfs_fsync ,
. release = jfs_release ,
2008-01-28 01:58:51 +03:00
. unlocked_ioctl = jfs_ioctl ,
2008-01-28 02:02:02 +03:00
# ifdef CONFIG_COMPAT
. compat_ioctl = jfs_compat_ioctl ,
# endif
2005-04-17 02:20:36 +04:00
} ;