aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 22:02:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 22:02:39 -0400
commitbbd9d6f7fbb0305c9a592bf05a32e87eb364a4ff (patch)
tree12b2bb4202b05f6ae6a43c6ce830a0472043dbe5 /fs/xfs
parent8e204874db000928e37199c2db82b7eb8966cc3c (diff)
parent5a9a43646cf709312d71eca71cef90ad802f28f9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (107 commits) vfs: use ERR_CAST for err-ptr tossing in lookup_instantiate_filp isofs: Remove global fs lock jffs2: fix IN_DELETE_SELF on overwriting rename() killing a directory fix IN_DELETE_SELF on overwriting rename() on ramfs et.al. mm/truncate.c: fix build for CONFIG_BLOCK not enabled fs:update the NOTE of the file_operations structure Remove dead code in dget_parent() AFS: Fix silly characters in a comment switch d_add_ci() to d_splice_alias() in "found negative" case as well simplify gfs2_lookup() jfs_lookup(): don't bother with . or .. get rid of useless dget_parent() in btrfs rename() and link() get rid of useless dget_parent() in fs/btrfs/ioctl.c fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers drivers: fix up various ->llseek() implementations fs: handle SEEK_HOLE/SEEK_DATA properly in all fs's that define their own llseek Ext4: handle SEEK_HOLE/SEEK_DATA generically Btrfs: implement our own ->llseek fs: add SEEK_HOLE and SEEK_DATA flags reiserfs: make reiserfs default to barrier=flush ... Fix up trivial conflicts in fs/xfs/linux-2.6/xfs_super.c due to the new shrinker callout for the inode cache, that clashed with the xfs code to start the periodic workers later.
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c17
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c27
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c71
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h5
-rw-r--r--fs/xfs/xfs_acl.h2
7 files changed, 60 insertions, 69 deletions
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
index 115ac6919533..cac48fe22ad5 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -219,7 +219,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
219} 219}
220 220
221int 221int
222xfs_check_acl(struct inode *inode, int mask, unsigned int flags) 222xfs_check_acl(struct inode *inode, int mask)
223{ 223{
224 struct xfs_inode *ip; 224 struct xfs_inode *ip;
225 struct posix_acl *acl; 225 struct posix_acl *acl;
@@ -235,7 +235,7 @@ xfs_check_acl(struct inode *inode, int mask, unsigned int flags)
235 if (!XFS_IFORK_Q(ip)) 235 if (!XFS_IFORK_Q(ip))
236 return -EAGAIN; 236 return -EAGAIN;
237 237
238 if (flags & IPERM_FLAG_RCU) { 238 if (mask & MAY_NOT_BLOCK) {
239 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) 239 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
240 return -ECHILD; 240 return -ECHILD;
241 return -EAGAIN; 241 return -EAGAIN;
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 26384fe3f26d..63e971e2b837 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1329,6 +1329,9 @@ xfs_end_io_direct_write(
1329 } else { 1329 } else {
1330 xfs_finish_ioend_sync(ioend); 1330 xfs_finish_ioend_sync(ioend);
1331 } 1331 }
1332
1333 /* XXX: probably should move into the real I/O completion handler */
1334 inode_dio_done(ioend->io_inode);
1332} 1335}
1333 1336
1334STATIC ssize_t 1337STATIC ssize_t
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 8073f61efb8e..cca00f49e092 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -127,6 +127,8 @@ xfs_iozero(
127STATIC int 127STATIC int
128xfs_file_fsync( 128xfs_file_fsync(
129 struct file *file, 129 struct file *file,
130 loff_t start,
131 loff_t end,
130 int datasync) 132 int datasync)
131{ 133{
132 struct inode *inode = file->f_mapping->host; 134 struct inode *inode = file->f_mapping->host;
@@ -138,6 +140,10 @@ xfs_file_fsync(
138 140
139 trace_xfs_file_fsync(ip); 141 trace_xfs_file_fsync(ip);
140 142
143 error = filemap_write_and_wait_range(inode->i_mapping, start, end);
144 if (error)
145 return error;
146
141 if (XFS_FORCED_SHUTDOWN(mp)) 147 if (XFS_FORCED_SHUTDOWN(mp))
142 return -XFS_ERROR(EIO); 148 return -XFS_ERROR(EIO);
143 149
@@ -875,18 +881,11 @@ xfs_file_aio_write(
875 /* Handle various SYNC-type writes */ 881 /* Handle various SYNC-type writes */
876 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 882 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
877 loff_t end = pos + ret - 1; 883 loff_t end = pos + ret - 1;
878 int error, error2;
879 884
880 xfs_rw_iunlock(ip, iolock); 885 xfs_rw_iunlock(ip, iolock);
881 error = filemap_write_and_wait_range(mapping, pos, end); 886 ret = -xfs_file_fsync(file, pos, end,
887 (file->f_flags & __O_SYNC) ? 0 : 1);
882 xfs_rw_ilock(ip, iolock); 888 xfs_rw_ilock(ip, iolock);
883
884 error2 = -xfs_file_fsync(file,
885 (file->f_flags & __O_SYNC) ? 0 : 1);
886 if (error)
887 ret = error;
888 else if (error2)
889 ret = error2;
890 } 889 }
891 890
892out_unlock: 891out_unlock:
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 25fd2cd6c8b0..9a72dda58bd0 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1024,11 +1024,6 @@ xfs_fs_put_super(
1024{ 1024{
1025 struct xfs_mount *mp = XFS_M(sb); 1025 struct xfs_mount *mp = XFS_M(sb);
1026 1026
1027 /*
1028 * Unregister the memory shrinker before we tear down the mount
1029 * structure so we don't have memory reclaim racing with us here.
1030 */
1031 xfs_inode_shrinker_unregister(mp);
1032 xfs_syncd_stop(mp); 1027 xfs_syncd_stop(mp);
1033 1028
1034 /* 1029 /*
@@ -1411,8 +1406,6 @@ xfs_fs_fill_super(
1411 sb->s_time_gran = 1; 1406 sb->s_time_gran = 1;
1412 set_posix_acl_flag(sb); 1407 set_posix_acl_flag(sb);
1413 1408
1414 xfs_inode_shrinker_register(mp);
1415
1416 error = xfs_mountfs(mp); 1409 error = xfs_mountfs(mp);
1417 if (error) 1410 if (error)
1418 goto out_filestream_unmount; 1411 goto out_filestream_unmount;
@@ -1439,7 +1432,6 @@ xfs_fs_fill_super(
1439 return 0; 1432 return 0;
1440 1433
1441 out_filestream_unmount: 1434 out_filestream_unmount:
1442 xfs_inode_shrinker_unregister(mp);
1443 xfs_filestream_unmount(mp); 1435 xfs_filestream_unmount(mp);
1444 out_free_sb: 1436 out_free_sb:
1445 xfs_freesb(mp); 1437 xfs_freesb(mp);
@@ -1458,8 +1450,6 @@ xfs_fs_fill_super(
1458 out_syncd_stop: 1450 out_syncd_stop:
1459 xfs_syncd_stop(mp); 1451 xfs_syncd_stop(mp);
1460 out_unmount: 1452 out_unmount:
1461 xfs_inode_shrinker_unregister(mp);
1462
1463 /* 1453 /*
1464 * Blow away any referenced inode in the filestreams cache. 1454 * Blow away any referenced inode in the filestreams cache.
1465 * This can and will cause log traffic as inodes go inactive 1455 * This can and will cause log traffic as inodes go inactive
@@ -1483,6 +1473,21 @@ xfs_fs_mount(
1483 return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); 1473 return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
1484} 1474}
1485 1475
1476static int
1477xfs_fs_nr_cached_objects(
1478 struct super_block *sb)
1479{
1480 return xfs_reclaim_inodes_count(XFS_M(sb));
1481}
1482
1483static void
1484xfs_fs_free_cached_objects(
1485 struct super_block *sb,
1486 int nr_to_scan)
1487{
1488 xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan);
1489}
1490
1486static const struct super_operations xfs_super_operations = { 1491static const struct super_operations xfs_super_operations = {
1487 .alloc_inode = xfs_fs_alloc_inode, 1492 .alloc_inode = xfs_fs_alloc_inode,
1488 .destroy_inode = xfs_fs_destroy_inode, 1493 .destroy_inode = xfs_fs_destroy_inode,
@@ -1496,6 +1501,8 @@ static const struct super_operations xfs_super_operations = {
1496 .statfs = xfs_fs_statfs, 1501 .statfs = xfs_fs_statfs,
1497 .remount_fs = xfs_fs_remount, 1502 .remount_fs = xfs_fs_remount,
1498 .show_options = xfs_fs_show_options, 1503 .show_options = xfs_fs_show_options,
1504 .nr_cached_objects = xfs_fs_nr_cached_objects,
1505 .free_cached_objects = xfs_fs_free_cached_objects,
1499}; 1506};
1500 1507
1501static struct file_system_type xfs_fs_type = { 1508static struct file_system_type xfs_fs_type = {
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 5cc158e52d4c..e4c938afb910 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -179,6 +179,8 @@ restart:
179 if (error == EFSCORRUPTED) 179 if (error == EFSCORRUPTED)
180 break; 180 break;
181 181
182 cond_resched();
183
182 } while (nr_found && !done); 184 } while (nr_found && !done);
183 185
184 if (skipped) { 186 if (skipped) {
@@ -984,6 +986,8 @@ restart:
984 986
985 *nr_to_scan -= XFS_LOOKUP_BATCH; 987 *nr_to_scan -= XFS_LOOKUP_BATCH;
986 988
989 cond_resched();
990
987 } while (nr_found && !done && *nr_to_scan > 0); 991 } while (nr_found && !done && *nr_to_scan > 0);
988 992
989 if (trylock && !done) 993 if (trylock && !done)
@@ -1001,7 +1005,7 @@ restart:
1001 * ensure that when we get more reclaimers than AGs we block rather 1005 * ensure that when we get more reclaimers than AGs we block rather
1002 * than spin trying to execute reclaim. 1006 * than spin trying to execute reclaim.
1003 */ 1007 */
1004 if (trylock && skipped && *nr_to_scan > 0) { 1008 if (skipped && (flags & SYNC_WAIT) && *nr_to_scan > 0) {
1005 trylock = 0; 1009 trylock = 0;
1006 goto restart; 1010 goto restart;
1007 } 1011 }
@@ -1019,44 +1023,38 @@ xfs_reclaim_inodes(
1019} 1023}
1020 1024
1021/* 1025/*
1022 * Inode cache shrinker. 1026 * Scan a certain number of inodes for reclaim.
1023 * 1027 *
1024 * When called we make sure that there is a background (fast) inode reclaim in 1028 * When called we make sure that there is a background (fast) inode reclaim in
1025 * progress, while we will throttle the speed of reclaim via doiing synchronous 1029 * progress, while we will throttle the speed of reclaim via doing synchronous
1026 * reclaim of inodes. That means if we come across dirty inodes, we wait for 1030 * reclaim of inodes. That means if we come across dirty inodes, we wait for
1027 * them to be cleaned, which we hope will not be very long due to the 1031 * them to be cleaned, which we hope will not be very long due to the
1028 * background walker having already kicked the IO off on those dirty inodes. 1032 * background walker having already kicked the IO off on those dirty inodes.
1029 */ 1033 */
1030static int 1034void
1031xfs_reclaim_inode_shrink( 1035xfs_reclaim_inodes_nr(
1032 struct shrinker *shrink, 1036 struct xfs_mount *mp,
1033 struct shrink_control *sc) 1037 int nr_to_scan)
1034{ 1038{
1035 struct xfs_mount *mp; 1039 /* kick background reclaimer and push the AIL */
1036 struct xfs_perag *pag; 1040 xfs_syncd_queue_reclaim(mp);
1037 xfs_agnumber_t ag; 1041 xfs_ail_push_all(mp->m_ail);
1038 int reclaimable;
1039 int nr_to_scan = sc->nr_to_scan;
1040 gfp_t gfp_mask = sc->gfp_mask;
1041
1042 mp = container_of(shrink, struct xfs_mount, m_inode_shrink);
1043 if (nr_to_scan) {
1044 /* kick background reclaimer and push the AIL */
1045 xfs_syncd_queue_reclaim(mp);
1046 xfs_ail_push_all(mp->m_ail);
1047 1042
1048 if (!(gfp_mask & __GFP_FS)) 1043 xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, &nr_to_scan);
1049 return -1; 1044}
1050 1045
1051 xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, 1046/*
1052 &nr_to_scan); 1047 * Return the number of reclaimable inodes in the filesystem for
1053 /* terminate if we don't exhaust the scan */ 1048 * the shrinker to determine how much to reclaim.
1054 if (nr_to_scan > 0) 1049 */
1055 return -1; 1050int
1056 } 1051xfs_reclaim_inodes_count(
1052 struct xfs_mount *mp)
1053{
1054 struct xfs_perag *pag;
1055 xfs_agnumber_t ag = 0;
1056 int reclaimable = 0;
1057 1057
1058 reclaimable = 0;
1059 ag = 0;
1060 while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { 1058 while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
1061 ag = pag->pag_agno + 1; 1059 ag = pag->pag_agno + 1;
1062 reclaimable += pag->pag_ici_reclaimable; 1060 reclaimable += pag->pag_ici_reclaimable;
@@ -1065,18 +1063,3 @@ xfs_reclaim_inode_shrink(
1065 return reclaimable; 1063 return reclaimable;
1066} 1064}
1067 1065
1068void
1069xfs_inode_shrinker_register(
1070 struct xfs_mount *mp)
1071{
1072 mp->m_inode_shrink.shrink = xfs_reclaim_inode_shrink;
1073 mp->m_inode_shrink.seeks = DEFAULT_SEEKS;
1074 register_shrinker(&mp->m_inode_shrink);
1075}
1076
1077void
1078xfs_inode_shrinker_unregister(
1079 struct xfs_mount *mp)
1080{
1081 unregister_shrinker(&mp->m_inode_shrink);
1082}
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index e914fd621746..941202e7ac6e 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -35,6 +35,8 @@ void xfs_quiesce_attr(struct xfs_mount *mp);
35void xfs_flush_inodes(struct xfs_inode *ip); 35void xfs_flush_inodes(struct xfs_inode *ip);
36 36
37int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); 37int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
38int xfs_reclaim_inodes_count(struct xfs_mount *mp);
39void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
38 40
39void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); 41void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
40void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip); 42void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip);
@@ -46,7 +48,4 @@ int xfs_inode_ag_iterator(struct xfs_mount *mp,
46 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), 48 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
47 int flags); 49 int flags);
48 50
49void xfs_inode_shrinker_register(struct xfs_mount *mp);
50void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
51
52#endif 51#endif
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 11dd72070cbb..0135e2a669d7 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -42,7 +42,7 @@ struct xfs_acl {
42#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) 42#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
43 43
44#ifdef CONFIG_XFS_POSIX_ACL 44#ifdef CONFIG_XFS_POSIX_ACL
45extern int xfs_check_acl(struct inode *inode, int mask, unsigned int flags); 45extern int xfs_check_acl(struct inode *inode, int mask);
46extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); 46extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
47extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); 47extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
48extern int xfs_acl_chmod(struct inode *inode); 48extern int xfs_acl_chmod(struct inode *inode);