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>
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 ;
mutex_lock ( & inode - > i_mutex ) ;
2005-04-17 02:20:36 +04:00
if ( ! ( inode - > i_state & I_DIRTY ) | |
( datasync & & ! ( inode - > i_state & I_DIRTY_DATASYNC ) ) ) {
/* Make sure committed changes hit the disk */
jfs_flush_journal ( JFS_SBI ( inode - > i_sb ) - > log , 1 ) ;
2011-07-17 04:44:56 +04:00
mutex_unlock ( & inode - > i_mutex ) ;
2005-04-17 02:20:36 +04:00
return rc ;
}
rc | = jfs_commit_inode ( inode , 1 ) ;
2011-07-17 04:44:56 +04:00
mutex_unlock ( & inode - > i_mutex ) ;
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 ) ;
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 )
{
struct inode * inode = dentry - > d_inode ;
int rc ;
rc = inode_change_ok ( inode , iattr ) ;
if ( rc )
return rc ;
2010-04-08 22:04:20 +04:00
if ( is_quota_modification ( inode , iattr ) )
2010-03-03 17:05:07 +03:00
dquot_initialize ( inode ) ;
2010-03-03 17:05:02 +03:00
if ( ( iattr - > ia_valid & ATTR_UID & & iattr - > ia_uid ! = inode - > i_uid ) | |
( iattr - > ia_valid & ATTR_GID & & 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 ) ;
2010-06-04 13:30:02 +04:00
rc = vmtruncate ( inode , iattr - > ia_size ) ;
if ( rc )
return rc ;
}
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 )
rc = jfs_acl_chmod ( inode ) ;
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 = {
2005-04-17 02:20:36 +04:00
. truncate = jfs_truncate ,
. setxattr = jfs_setxattr ,
. getxattr = jfs_getxattr ,
. listxattr = jfs_listxattr ,
. removexattr = jfs_removexattr ,
. setattr = jfs_setattr ,
2010-03-03 17:05:02 +03:00
# ifdef CONFIG_JFS_POSIX_ACL
2009-08-28 23:29:03 +04:00
. check_acl = jfs_check_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 ,
2006-10-01 10:28:48 +04:00
. write = do_sync_write ,
. read = do_sync_read ,
2005-04-17 02:20:36 +04:00
. aio_read = generic_file_aio_read ,
. aio_write = generic_file_aio_write ,
. mmap = generic_file_mmap ,
2006-10-30 20:47:02 +03:00
. splice_read = generic_file_splice_read ,
. splice_write = generic_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
} ;