* largeio mount and performance impact @ 2006-09-23 13:27 Sebastian Brings 2006-09-23 16:34 ` Eric Sandeen 2006-09-25 8:38 ` Data type overflow in xfs_trans_unreserve_and_mod_sb Shailendra Tripathi 0 siblings, 2 replies; 10+ messages in thread From: Sebastian Brings @ 2006-09-23 13:27 UTC (permalink / raw) To: xfs In a different thread I read about the largeio mount option for XFS. Now I wonder if the problems I recently ran in have been caused by this. After a system uprgade from sles9 sp2 to sp3 one app started misbehaving. Before the upgrade it used 15% CPU, after the upgrade it was 90+% and the performance dropped by about 50%. The app is writing a wave audio file, and for every 3840 bytes of audio samples it appends, it updates the RIFF header of the file. All of this was done using the buffered fopen/fwrite/... C library functions. An strace showed that seeking to the beginning of the file also triggered a 12MiB read(2) call, and seeking to the end, for example to 13MiB, translated to a seek(2) to offset 1mib and a read(2) of 12 MiB. Initiall I assumed something very strange had happened to the C lib defaults. Otoh 12MiB is the swidth of the filesystem, so I assume that the C lib got the 12 MiB optimal IO size from XFS and therefore behaved as described above. Could that be? Regards Sebastian ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: largeio mount and performance impact 2006-09-23 13:27 largeio mount and performance impact Sebastian Brings @ 2006-09-23 16:34 ` Eric Sandeen 2006-09-24 13:41 ` Sebastian Brings 2006-09-25 8:38 ` Data type overflow in xfs_trans_unreserve_and_mod_sb Shailendra Tripathi 1 sibling, 1 reply; 10+ messages in thread From: Eric Sandeen @ 2006-09-23 16:34 UTC (permalink / raw) To: Sebastian Brings; +Cc: xfs Sebastian Brings wrote: > In a different thread I read about the largeio mount option for XFS. Now > I wonder if the problems I recently ran in have been caused by this. > > After a system uprgade from sles9 sp2 to sp3 one app started > misbehaving. Before the upgrade it used 15% CPU, after the upgrade it > was 90+% and the performance dropped by about 50%. The app is writing a > wave audio file, and for every 3840 bytes of audio samples it appends, > it updates the RIFF header of the file. All of this was done using the > buffered fopen/fwrite/... C library functions. > An strace showed that seeking to the beginning of the file also > triggered a 12MiB read(2) call, and seeking to the end, for example to > 13MiB, translated to a seek(2) to offset 1mib and a read(2) of 12 MiB. > > Initiall I assumed something very strange had happened to the C lib > defaults. Otoh 12MiB is the swidth of the filesystem, so I assume that > the C lib got the 12 MiB optimal IO size from XFS and therefore behaved > as described above. Could that be? Unless you specify the largeio mount option, I don't -think- any of this is exposed. What does stat -c %o <file> say? Did this strace behavior change from sp2 to sp3? -Eric ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: largeio mount and performance impact 2006-09-23 16:34 ` Eric Sandeen @ 2006-09-24 13:41 ` Sebastian Brings 2006-09-24 13:47 ` Sebastian Brings 0 siblings, 1 reply; 10+ messages in thread From: Sebastian Brings @ 2006-09-24 13:41 UTC (permalink / raw) To: Eric Sandeen; +Cc: xfs > -----Original Message----- > From: Eric Sandeen [mailto:sandeen@sandeen.net] > Sent: Samstag, 23. September 2006 18:34 > To: Sebastian Brings > Cc: xfs@oss.sgi.com > Subject: Re: largeio mount and performance impact > > Sebastian Brings wrote: > > In a different thread I read about the largeio mount option for XFS. Now > > I wonder if the problems I recently ran in have been caused by this. > > > > After a system uprgade from sles9 sp2 to sp3 one app started > > misbehaving. Before the upgrade it used 15% CPU, after the upgrade it > > was 90+% and the performance dropped by about 50%. The app is writing a > > wave audio file, and for every 3840 bytes of audio samples it appends, > > it updates the RIFF header of the file. All of this was done using the > > buffered fopen/fwrite/... C library functions. > > An strace showed that seeking to the beginning of the file also > > triggered a 12MiB read(2) call, and seeking to the end, for example to > > 13MiB, translated to a seek(2) to offset 1mib and a read(2) of 12 MiB. > > > > Initiall I assumed something very strange had happened to the C lib > > defaults. Otoh 12MiB is the swidth of the filesystem, so I assume that > > the C lib got the 12 MiB optimal IO size from XFS and therefore behaved > > as described above. Could that be? > > Unless you specify the largeio mount option, I don't -think- any of this > is exposed. > > What does stat -c %o <file> say? > > Did this strace behavior change from sp2 to sp3? > > -Eric Stat seems to report 12MB: # stat -c %o sebastian.tgz 12582912 Mount does not have largeio set explicitly. But this is a CXFS, so this may change tings: /dev/cxvm/fs1 on /shares/fs1 type xfs (rw,noatime,client_timeout=1s,retry=0,server_list=(meta01, meta02),filestreams,quota,mtpt=/shares/fs1) I don't have strace data from the app running under sp2. But changing the default library buffer size to a more reasonable size after the fopen(), the app behaved normal again. Sebastian ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: largeio mount and performance impact 2006-09-24 13:41 ` Sebastian Brings @ 2006-09-24 13:47 ` Sebastian Brings 0 siblings, 0 replies; 10+ messages in thread From: Sebastian Brings @ 2006-09-24 13:47 UTC (permalink / raw) To: Eric Sandeen; +Cc: xfs > -----Original Message----- > From: xfs-bounce@oss.sgi.com [mailto:xfs-bounce@oss.sgi.com] On Behalf Of > Sebastian Brings > Sent: Sonntag, 24. September 2006 15:42 > To: Eric Sandeen > Cc: xfs@oss.sgi.com > Subject: RE: largeio mount and performance impact > > > -----Original Message----- > > From: Eric Sandeen [mailto:sandeen@sandeen.net] > > Sent: Samstag, 23. September 2006 18:34 > > To: Sebastian Brings > > Cc: xfs@oss.sgi.com > > Subject: Re: largeio mount and performance impact > > > > Sebastian Brings wrote: > > > In a different thread I read about the largeio mount option for XFS. > Now > > > I wonder if the problems I recently ran in have been caused by this. > > > > > > After a system uprgade from sles9 sp2 to sp3 one app started > > > misbehaving. Before the upgrade it used 15% CPU, after the upgrade > it > > > was 90+% and the performance dropped by about 50%. The app is > writing a > > > wave audio file, and for every 3840 bytes of audio samples it > appends, > > > it updates the RIFF header of the file. All of this was done using > the > > > buffered fopen/fwrite/... C library functions. > > > An strace showed that seeking to the beginning of the file also > > > triggered a 12MiB read(2) call, and seeking to the end, for example > to > > > 13MiB, translated to a seek(2) to offset 1mib and a read(2) of 12 > MiB. > > > > > > Initiall I assumed something very strange had happened to the C lib > > > defaults. Otoh 12MiB is the swidth of the filesystem, so I assume > that > > > the C lib got the 12 MiB optimal IO size from XFS and therefore > behaved > > > as described above. Could that be? > > > > Unless you specify the largeio mount option, I don't -think- any of > this > > is exposed. > > > > What does stat -c %o <file> say? > > > > Did this strace behavior change from sp2 to sp3? > > > > -Eric > > > Stat seems to report 12MB: > > # stat -c %o sebastian.tgz > 12582912 > > Mount does not have largeio set explicitly. But this is a CXFS, so this > may change tings: > > /dev/cxvm/fs1 on /shares/fs1 type xfs > (rw,noatime,client_timeout=1s,retry=0,server_list=(meta01, > meta02),filestreams,quota,mtpt=/shares/fs1) > > > I don't have strace data from the app running under sp2. But changing > the default library buffer size to a more reasonable size after the > fopen(), the app behaved normal again. > > > Sebastian > Now I remember. Filestreams was added during the update. Maybe that makes the difference. Anyways, I just wanted to point out that largeio mount option may have unexpected side effects Sebastian ^ permalink raw reply [flat|nested] 10+ messages in thread
* Data type overflow in xfs_trans_unreserve_and_mod_sb 2006-09-23 13:27 largeio mount and performance impact Sebastian Brings 2006-09-23 16:34 ` Eric Sandeen @ 2006-09-25 8:38 ` Shailendra Tripathi 2006-09-25 14:32 ` Eric Sandeen 2006-10-11 5:25 ` David Chinner 1 sibling, 2 replies; 10+ messages in thread From: Shailendra Tripathi @ 2006-09-25 8:38 UTC (permalink / raw) To: David Chinner; +Cc: xfs, Timothy Shimmin [-- Attachment #1: Type: text/plain, Size: 1743 bytes --] Hi David, As part of fixing xfs_reserve_blocks issue, you might want to fix an issue in xfs_trans_unreserve_and_mod_sb as well. Since, I am on much older version, my patch is not applicable on newer trees. However, the patch is attached for your reference. The problem is as below: Superblock modifications required during transaction are stored in delta fields in transaction. These fields are applied to the superblock when transaction commits. The in-core superblock changes are done in xfs_trans_unreserve_and_mod_sb. It calls xfs_mod_incore_sb_batch function to apply the changes. This function tries to apply the deltas and if it fails for any reason, it backs out all the changes. One typical modification done is like that: case XFS_SBS_DBLOCKS: lcounter = (long long)mp->m_sb.sb_dblocks; lcounter += delta; if (lcounter < 0) { ASSERT(0); return (XFS_ERROR(EINVAL)); } mp->m_sb.sb_dblocks = lcounter; return (0); So, when it returns EINVAL, the second part of the code backs out the changes made to superblock. However, the worst part is that xfs_trans_unreserve_and_mod_sb does not return any error value. The transaction appears to be committed peacefully without returning the error. You don't notice this unless you do I/O on the filesystem. Later, it hits some sort of in-memory corruption or other errors. We hit this issue in our testing we tried to grow the filesystem from from 100GB to 10000GB. This is beyond the interger (31 bits) limit and, hence, for dblocks and fdblocks, xfs_mod_sb struct does not pass in correct data. [-- Attachment #2: xfs-sb-mod-growfs.patch --] [-- Type: text/x-patch, Size: 3709 bytes --] diff -urNp -X kernel-2.6.7-dontdiff kernel-2.6.7-orig/fs/xfs/xfs_mount.c kernel-2.6.7-modif/fs/xfs/xfs_mount.c --- kernel-2.6.7-orig/fs/xfs/xfs_mount.c +++ kernel-2.6.7-modif/fs/xfs/xfs_mount.c @@ -1286,7 +1286,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fi */ STATIC int xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field, - int delta, int rsvd) + long delta, int rsvd) { int scounter; /* short counter for 32 bit fields */ long long lcounter; /* long counter for 64 bit fields */ diff -urNp -X kernel-2.6.7-dontdiff kernel-2.6.7-orig/fs/xfs/xfs_mount.h kernel-2.6.7-modif/fs/xfs/xfs_mount.h --- kernel-2.6.7-orig/fs/xfs/xfs_mount.h +++ kernel-2.6.7-modif/fs/xfs/xfs_mount.h @@ -551,10 +551,11 @@ static inline xfs_agblock_t XFS_DADDR_TO /* * This structure is for use by the xfs_mod_incore_sb_batch() routine. + * xfs_growfs can specify a few fields which are more than int limit */ typedef struct xfs_mod_sb { xfs_sb_field_t msb_field; /* Field to modify, see below */ - int msb_delta; /* Change to make to specified field */ + long msb_delta; /* Change to make to specified field */ } xfs_mod_sb_t; #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock), PINOD) diff -urNp -X kernel-2.6.7-dontdiff kernel-2.6.7-orig/fs/xfs/xfs_trans.c kernel-2.6.7-modif/fs/xfs/xfs_trans.c --- kernel-2.6.7-orig/fs/xfs/xfs_trans.c +++ kernel-2.6.7-modif/fs/xfs/xfs_trans.c @@ -590,62 +590,62 @@ xfs_trans_unreserve_and_mod_sb( if (tp->t_flags & XFS_TRANS_SB_DIRTY) { if (tp->t_icount_delta != 0) { msbp->msb_field = XFS_SBS_ICOUNT; - msbp->msb_delta = (int)tp->t_icount_delta; + msbp->msb_delta = tp->t_icount_delta; msbp++; } if (tp->t_ifree_delta != 0) { msbp->msb_field = XFS_SBS_IFREE; - msbp->msb_delta = (int)tp->t_ifree_delta; + msbp->msb_delta = tp->t_ifree_delta; msbp++; } if (tp->t_fdblocks_delta != 0) { msbp->msb_field = XFS_SBS_FDBLOCKS; - msbp->msb_delta = (int)tp->t_fdblocks_delta; + msbp->msb_delta = tp->t_fdblocks_delta; msbp++; } if (tp->t_frextents_delta != 0) { msbp->msb_field = XFS_SBS_FREXTENTS; - msbp->msb_delta = (int)tp->t_frextents_delta; + msbp->msb_delta = tp->t_frextents_delta; msbp++; } if (tp->t_dblocks_delta != 0) { msbp->msb_field = XFS_SBS_DBLOCKS; - msbp->msb_delta = (int)tp->t_dblocks_delta; + msbp->msb_delta = tp->t_dblocks_delta; msbp++; } if (tp->t_agcount_delta != 0) { msbp->msb_field = XFS_SBS_AGCOUNT; - msbp->msb_delta = (int)tp->t_agcount_delta; + msbp->msb_delta = tp->t_agcount_delta; msbp++; } if (tp->t_imaxpct_delta != 0) { msbp->msb_field = XFS_SBS_IMAX_PCT; - msbp->msb_delta = (int)tp->t_imaxpct_delta; + msbp->msb_delta = tp->t_imaxpct_delta; msbp++; } if (tp->t_rextsize_delta != 0) { msbp->msb_field = XFS_SBS_REXTSIZE; - msbp->msb_delta = (int)tp->t_rextsize_delta; + msbp->msb_delta = tp->t_rextsize_delta; msbp++; } if (tp->t_rbmblocks_delta != 0) { msbp->msb_field = XFS_SBS_RBMBLOCKS; - msbp->msb_delta = (int)tp->t_rbmblocks_delta; + msbp->msb_delta = tp->t_rbmblocks_delta; msbp++; } if (tp->t_rblocks_delta != 0) { msbp->msb_field = XFS_SBS_RBLOCKS; - msbp->msb_delta = (int)tp->t_rblocks_delta; + msbp->msb_delta = tp->t_rblocks_delta; msbp++; } if (tp->t_rextents_delta != 0) { msbp->msb_field = XFS_SBS_REXTENTS; - msbp->msb_delta = (int)tp->t_rextents_delta; + msbp->msb_delta = tp->t_rextents_delta; msbp++; } if (tp->t_rextslog_delta != 0) { msbp->msb_field = XFS_SBS_REXTSLOG; - msbp->msb_delta = (int)tp->t_rextslog_delta; + msbp->msb_delta = tp->t_rextslog_delta; msbp++; } } ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Data type overflow in xfs_trans_unreserve_and_mod_sb 2006-09-25 8:38 ` Data type overflow in xfs_trans_unreserve_and_mod_sb Shailendra Tripathi @ 2006-09-25 14:32 ` Eric Sandeen 2006-09-25 14:52 ` Shailendra Tripathi 2006-10-11 5:25 ` David Chinner 1 sibling, 1 reply; 10+ messages in thread From: Eric Sandeen @ 2006-09-25 14:32 UTC (permalink / raw) To: Shailendra Tripathi; +Cc: David Chinner, xfs, Timothy Shimmin Shailendra Tripathi wrote: > Hi David, > As part of fixing xfs_reserve_blocks issue, you might want to > fix an issue in xfs_trans_unreserve_and_mod_sb as well. Since, I am on > much older version, my patch is not applicable on newer trees. However, > the patch is attached for your reference. > > The problem is as below: > > Superblock modifications required during transaction are stored in delta > fields in transaction. These fields are applied to the superblock when > transaction commits. > > The in-core superblock changes are done in > xfs_trans_unreserve_and_mod_sb. It calls xfs_mod_incore_sb_batch > function to apply the changes. This function tries to apply the deltas > and if it fails for any reason, it backs out all the changes. One > typical modification done is like that: > > case XFS_SBS_DBLOCKS: > lcounter = (long long)mp->m_sb.sb_dblocks; > lcounter += delta; > if (lcounter < 0) { > ASSERT(0); > return (XFS_ERROR(EINVAL)); > } > mp->m_sb.sb_dblocks = lcounter; > return (0); > > So, when it returns EINVAL, the second part of the code backs out the > changes made to superblock. However, the worst part is that > xfs_trans_unreserve_and_mod_sb does not return any error value. Hm, yep, just ASSERT(error == 0); I suppose this is the trickiness of canceling a transaction at some points... > The > transaction appears to be committed peacefully without returning the > error. You don't notice this unless you do I/O on the filesystem. Later, > it hits some sort of in-memory corruption or other errors. > > We hit this issue in our testing we tried to grow the filesystem from > from 100GB to 10000GB. This is beyond the interger (31 bits) limit and, > hence, for dblocks and fdblocks, xfs_mod_sb struct does not pass in > correct data. > > First thoughts, "long" won't help on 32 bit machines, perhaps this should be an explicitly-sized 64-bit type? -Eric p.s. good to see agami's recently active participation on the list! ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Data type overflow in xfs_trans_unreserve_and_mod_sb 2006-09-25 14:32 ` Eric Sandeen @ 2006-09-25 14:52 ` Shailendra Tripathi 0 siblings, 0 replies; 10+ messages in thread From: Shailendra Tripathi @ 2006-09-25 14:52 UTC (permalink / raw) To: Eric Sandeen; +Cc: David Chinner, xfs, Timothy Shimmin Eric Sandeen wrote: > Hm, yep, just ASSERT(error == 0); > > I suppose this is the trickiness of canceling a transaction at some > points... Yes, you are right. At the point where it is being applied, all the things can't be reverted back as XFS does not store the "before-image". However, typically in most of such cases, XFS goes ahead with shutting down the filesystem assuming these to be catastrophic or incorrigible errors requiring manual intervention. > First thoughts, "long" won't help on 32 bit machines, perhaps this > should be an explicitly-sized 64-bit type > -Eric > > p.s. good to see agami's recently active participation on the list! > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Data type overflow in xfs_trans_unreserve_and_mod_sb 2006-09-25 8:38 ` Data type overflow in xfs_trans_unreserve_and_mod_sb Shailendra Tripathi 2006-09-25 14:32 ` Eric Sandeen @ 2006-10-11 5:25 ` David Chinner 2006-10-13 6:13 ` David Chinner 1 sibling, 1 reply; 10+ messages in thread From: David Chinner @ 2006-10-11 5:25 UTC (permalink / raw) To: Shailendra Tripathi; +Cc: sandeen, xfs, Timothy Shimmin On Mon, Sep 25, 2006 at 02:08:11PM +0530, Shailendra Tripathi wrote: > Hi David, > As part of fixing xfs_reserve_blocks issue, you might want to > fix an issue in xfs_trans_unreserve_and_mod_sb as well. Since, I am on > much older version, my patch is not applicable on newer trees. However, > the patch is attached for your reference. > > The problem is as below: > > Superblock modifications required during transaction are stored in delta > fields in transaction. These fields are applied to the superblock when > transaction commits. > > The in-core superblock changes are done in > xfs_trans_unreserve_and_mod_sb. It calls xfs_mod_incore_sb_batch > function to apply the changes. This function tries to apply the deltas > and if it fails for any reason, it backs out all the changes. One > typical modification done is like that: > > case XFS_SBS_DBLOCKS: > lcounter = (long long)mp->m_sb.sb_dblocks; > lcounter += delta; > if (lcounter < 0) { > ASSERT(0); > return (XFS_ERROR(EINVAL)); > } > mp->m_sb.sb_dblocks = lcounter; > return (0); > > So, when it returns EINVAL, the second part of the code backs out the > changes made to superblock. However, the worst part is that > xfs_trans_unreserve_and_mod_sb does not return any error value. That's because the error checking is supposed to occur before you commit the transaction e.g. during xfs_trans_mod_sb() that calculates the deltas. In which case: case XFS_TRANS_SB_DBLOCKS: ASSERT(delta > 0); tp->t_dblocks_delta += delta; break; You should assert fail there is the delta is less than zero. To me, it is obvious these ASSERTS were placed long ago to be a landmine for someone to trip over when thea deltas start to overflow. Far-sighted, self documenting code - just the way it should be ;) So, looking a little deeper: void xfs_trans_mod_sb( xfs_trans_t *tp, uint field, long delta) This function can't take more than 31 bits of delta on a 32 bit machine so your patch only fixed the problem on 64 bit platforms. Given that we can support 16TB filesystems on 32 bit platforms, they need to be fixed in some way here as well. Also, the transaction delta fields are all longs - they overflow in the same manner. Eric, you suggested specific 64 bit types - I think that's really the way to fix this, but it's a much bigger change... Cheers, Dave. -- Dave Chinner Principal Engineer SGI Australian Software Group ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Data type overflow in xfs_trans_unreserve_and_mod_sb 2006-10-11 5:25 ` David Chinner @ 2006-10-13 6:13 ` David Chinner 2006-10-13 8:31 ` Shailendra Tripathi 0 siblings, 1 reply; 10+ messages in thread From: David Chinner @ 2006-10-13 6:13 UTC (permalink / raw) To: Shailendra Tripathi; +Cc: sandeen, xfs, Timothy Shimmin On Wed, Oct 11, 2006 at 03:25:57PM +1000, David Chinner wrote: > On Mon, Sep 25, 2006 at 02:08:11PM +0530, Shailendra Tripathi wrote: > > Hi David, > > As part of fixing xfs_reserve_blocks issue, you might want to > > fix an issue in xfs_trans_unreserve_and_mod_sb as well. Since, I am on > > much older version, my patch is not applicable on newer trees. However, > > the patch is attached for your reference. > > > > The problem is as below: > > > > Superblock modifications required during transaction are stored in delta > > fields in transaction. These fields are applied to the superblock when > > transaction commits. ..... > So, looking a little deeper: > > void > xfs_trans_mod_sb( > xfs_trans_t *tp, > uint field, > long delta) > > This function can't take more than 31 bits of delta on a 32 bit machine > so your patch only fixed the problem on 64 bit platforms. Given that we can > support 16TB filesystems on 32 bit platforms, they need to be fixed in > some way here as well. > > Also, the transaction delta fields are all longs - they overflow in the same > manner. > > Eric, you suggested specific 64 bit types - I think that's really the > way to fix this, but it's a much bigger change... Shailendra, here's a patch that passes XFSQA that changes this all to 64 bit types. I've had to fix various type abuses that weren't obvious because gcc fails to warn when you pass a uint into a function parameter that is declared as int64_t..... I haven't tested the >2TB grow case yet, but it should work now on both 32bit and 64 bit platforms with this patch. Is there anything I missed here in the conversion? Cheers, Dave. -- Dave Chinner Principal Engineer SGI Australian Software Group --- fs/xfs/xfs_bmap.c | 26 +++++++++++++------------- fs/xfs/xfs_mount.c | 15 +++++++-------- fs/xfs/xfs_mount.h | 7 ++++--- fs/xfs/xfs_trans.c | 32 ++++++++++++++++---------------- fs/xfs/xfs_trans.h | 42 +++++++++++++++++++++--------------------- 5 files changed, 61 insertions(+), 61 deletions(-) Index: 2.6.x-xfs-new/fs/xfs/xfs_mount.c =================================================================== --- 2.6.x-xfs-new.orig/fs/xfs/xfs_mount.c 2006-10-13 12:07:41.337353137 +1000 +++ 2.6.x-xfs-new/fs/xfs/xfs_mount.c 2006-10-13 16:11:54.646069045 +1000 @@ -55,9 +55,9 @@ STATIC void xfs_icsb_destroy_counters(xf STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, int); STATIC void xfs_icsb_sync_counters(xfs_mount_t *); STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, - int, int); + int64_t, int); STATIC int xfs_icsb_modify_counters_locked(xfs_mount_t *, xfs_sb_field_t, - int, int); + int64_t, int); STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); #else @@ -1251,7 +1251,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fi */ int xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field, - int delta, int rsvd) + int64_t delta, int rsvd) { int scounter; /* short counter for 32 bit fields */ long long lcounter; /* long counter for 64 bit fields */ @@ -1283,7 +1283,6 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t * mp->m_sb.sb_ifree = lcounter; return 0; case XFS_SBS_FDBLOCKS: - lcounter = (long long) mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); @@ -1414,7 +1413,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t * * routine to do the work. */ int -xfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd) +xfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int64_t delta, int rsvd) { unsigned long s; int status; @@ -2052,7 +2051,7 @@ STATIC int xfs_icsb_modify_counters_int( xfs_mount_t *mp, xfs_sb_field_t field, - int delta, + int64_t delta, int rsvd, int flags) { @@ -2149,7 +2148,7 @@ STATIC int xfs_icsb_modify_counters( xfs_mount_t *mp, xfs_sb_field_t field, - int delta, + int64_t delta, int rsvd) { return xfs_icsb_modify_counters_int(mp, field, delta, rsvd, 0); @@ -2162,7 +2161,7 @@ STATIC int xfs_icsb_modify_counters_locked( xfs_mount_t *mp, xfs_sb_field_t field, - int delta, + int64_t delta, int rsvd) { return xfs_icsb_modify_counters_int(mp, field, delta, Index: 2.6.x-xfs-new/fs/xfs/xfs_mount.h =================================================================== --- 2.6.x-xfs-new.orig/fs/xfs/xfs_mount.h 2006-10-13 12:07:41.405344379 +1000 +++ 2.6.x-xfs-new/fs/xfs/xfs_mount.h 2006-10-13 12:13:43.478699896 +1000 @@ -576,10 +576,11 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, /* * This structure is for use by the xfs_mod_incore_sb_batch() routine. + * xfs_growfs can specify a few fields which are more than int limit */ typedef struct xfs_mod_sb { xfs_sb_field_t msb_field; /* Field to modify, see below */ - int msb_delta; /* Change to make to specified field */ + int64_t msb_delta; /* Change to make to specified field */ } xfs_mod_sb_t; #define XFS_MOUNT_ILOCK(mp) mutex_lock(&((mp)->m_ilock)) @@ -597,9 +598,9 @@ extern int xfs_unmountfs(xfs_mount_t *, extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *); extern int xfs_unmountfs_writesb(xfs_mount_t *); extern int xfs_unmount_flush(xfs_mount_t *, int); -extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int); +extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t, - int, int); + int64_t, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); Index: 2.6.x-xfs-new/fs/xfs/xfs_trans.c =================================================================== --- 2.6.x-xfs-new.orig/fs/xfs/xfs_trans.c 2006-10-13 12:07:41.413343349 +1000 +++ 2.6.x-xfs-new/fs/xfs/xfs_trans.c 2006-10-13 12:13:43.478699896 +1000 @@ -339,7 +339,7 @@ xfs_trans_reserve( */ if (blocks > 0) { error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, - -blocks, rsvd); + -((int64_t)blocks), rsvd); if (error != 0) { current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); return (XFS_ERROR(ENOSPC)); @@ -380,7 +380,7 @@ xfs_trans_reserve( */ if (rtextents > 0) { error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FREXTENTS, - -rtextents, rsvd); + -((int64_t)rtextents), rsvd); if (error) { error = XFS_ERROR(ENOSPC); goto undo_log; @@ -410,7 +410,7 @@ undo_log: undo_blocks: if (blocks > 0) { (void) xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, - blocks, rsvd); + (int64_t)blocks, rsvd); tp->t_blk_res = 0; } @@ -432,7 +432,7 @@ void xfs_trans_mod_sb( xfs_trans_t *tp, uint field, - long delta) + int64_t delta) { switch (field) { @@ -663,62 +663,62 @@ xfs_trans_unreserve_and_mod_sb( if (tp->t_flags & XFS_TRANS_SB_DIRTY) { if (tp->t_icount_delta != 0) { msbp->msb_field = XFS_SBS_ICOUNT; - msbp->msb_delta = (int)tp->t_icount_delta; + msbp->msb_delta = tp->t_icount_delta; msbp++; } if (tp->t_ifree_delta != 0) { msbp->msb_field = XFS_SBS_IFREE; - msbp->msb_delta = (int)tp->t_ifree_delta; + msbp->msb_delta = tp->t_ifree_delta; msbp++; } if (tp->t_fdblocks_delta != 0) { msbp->msb_field = XFS_SBS_FDBLOCKS; - msbp->msb_delta = (int)tp->t_fdblocks_delta; + msbp->msb_delta = tp->t_fdblocks_delta; msbp++; } if (tp->t_frextents_delta != 0) { msbp->msb_field = XFS_SBS_FREXTENTS; - msbp->msb_delta = (int)tp->t_frextents_delta; + msbp->msb_delta = tp->t_frextents_delta; msbp++; } if (tp->t_dblocks_delta != 0) { msbp->msb_field = XFS_SBS_DBLOCKS; - msbp->msb_delta = (int)tp->t_dblocks_delta; + msbp->msb_delta = tp->t_dblocks_delta; msbp++; } if (tp->t_agcount_delta != 0) { msbp->msb_field = XFS_SBS_AGCOUNT; - msbp->msb_delta = (int)tp->t_agcount_delta; + msbp->msb_delta = tp->t_agcount_delta; msbp++; } if (tp->t_imaxpct_delta != 0) { msbp->msb_field = XFS_SBS_IMAX_PCT; - msbp->msb_delta = (int)tp->t_imaxpct_delta; + msbp->msb_delta = tp->t_imaxpct_delta; msbp++; } if (tp->t_rextsize_delta != 0) { msbp->msb_field = XFS_SBS_REXTSIZE; - msbp->msb_delta = (int)tp->t_rextsize_delta; + msbp->msb_delta = tp->t_rextsize_delta; msbp++; } if (tp->t_rbmblocks_delta != 0) { msbp->msb_field = XFS_SBS_RBMBLOCKS; - msbp->msb_delta = (int)tp->t_rbmblocks_delta; + msbp->msb_delta = tp->t_rbmblocks_delta; msbp++; } if (tp->t_rblocks_delta != 0) { msbp->msb_field = XFS_SBS_RBLOCKS; - msbp->msb_delta = (int)tp->t_rblocks_delta; + msbp->msb_delta = tp->t_rblocks_delta; msbp++; } if (tp->t_rextents_delta != 0) { msbp->msb_field = XFS_SBS_REXTENTS; - msbp->msb_delta = (int)tp->t_rextents_delta; + msbp->msb_delta = tp->t_rextents_delta; msbp++; } if (tp->t_rextslog_delta != 0) { msbp->msb_field = XFS_SBS_REXTSLOG; - msbp->msb_delta = (int)tp->t_rextslog_delta; + msbp->msb_delta = tp->t_rextslog_delta; msbp++; } } Index: 2.6.x-xfs-new/fs/xfs/xfs_trans.h =================================================================== --- 2.6.x-xfs-new.orig/fs/xfs/xfs_trans.h 2006-10-13 12:07:41.413343349 +1000 +++ 2.6.x-xfs-new/fs/xfs/xfs_trans.h 2006-10-13 12:13:43.478699896 +1000 @@ -350,25 +350,25 @@ typedef struct xfs_trans { xfs_trans_callback_t t_callback; /* transaction callback */ void *t_callarg; /* callback arg */ unsigned int t_flags; /* misc flags */ - long t_icount_delta; /* superblock icount change */ - long t_ifree_delta; /* superblock ifree change */ - long t_fdblocks_delta; /* superblock fdblocks chg */ - long t_res_fdblocks_delta; /* on-disk only chg */ - long t_frextents_delta;/* superblock freextents chg*/ - long t_res_frextents_delta; /* on-disk only chg */ + int64_t t_icount_delta; /* superblock icount change */ + int64_t t_ifree_delta; /* superblock ifree change */ + int64_t t_fdblocks_delta; /* superblock fdblocks chg */ + int64_t t_res_fdblocks_delta; /* on-disk only chg */ + int64_t t_frextents_delta;/* superblock freextents chg*/ + int64_t t_res_frextents_delta; /* on-disk only chg */ #ifdef DEBUG - long t_ag_freeblks_delta; /* debugging counter */ - long t_ag_flist_delta; /* debugging counter */ - long t_ag_btree_delta; /* debugging counter */ + int64_t t_ag_freeblks_delta; /* debugging counter */ + int64_t t_ag_flist_delta; /* debugging counter */ + int64_t t_ag_btree_delta; /* debugging counter */ #endif - long t_dblocks_delta;/* superblock dblocks change */ - long t_agcount_delta;/* superblock agcount change */ - long t_imaxpct_delta;/* superblock imaxpct change */ - long t_rextsize_delta;/* superblock rextsize chg */ - long t_rbmblocks_delta;/* superblock rbmblocks chg */ - long t_rblocks_delta;/* superblock rblocks change */ - long t_rextents_delta;/* superblocks rextents chg */ - long t_rextslog_delta;/* superblocks rextslog chg */ + int64_t t_dblocks_delta;/* superblock dblocks change */ + int64_t t_agcount_delta;/* superblock agcount change */ + int64_t t_imaxpct_delta;/* superblock imaxpct change */ + int64_t t_rextsize_delta;/* superblock rextsize chg */ + int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ + int64_t t_rblocks_delta;/* superblock rblocks change */ + int64_t t_rextents_delta;/* superblocks rextents chg */ + int64_t t_rextslog_delta;/* superblocks rextslog chg */ unsigned int t_items_free; /* log item descs free */ xfs_log_item_chunk_t t_items; /* first log item desc chunk */ xfs_trans_header_t t_header; /* header for in-log trans */ @@ -932,9 +932,9 @@ typedef struct xfs_trans { #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) #ifdef DEBUG -#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (long)d) -#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (long)d) -#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (long)d) +#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) +#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) +#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) #else #define xfs_trans_agblocks_delta(tp, d) #define xfs_trans_agflist_delta(tp, d) @@ -950,7 +950,7 @@ xfs_trans_t *_xfs_trans_alloc(struct xfs xfs_trans_t *xfs_trans_dup(xfs_trans_t *); int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, uint, uint); -void xfs_trans_mod_sb(xfs_trans_t *, uint, long); +void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, int, uint); int xfs_trans_read_buf(struct xfs_mount *, xfs_trans_t *, Index: 2.6.x-xfs-new/fs/xfs/xfs_bmap.c =================================================================== --- 2.6.x-xfs-new.orig/fs/xfs/xfs_bmap.c 2006-10-13 11:47:18.195899267 +1000 +++ 2.6.x-xfs-new/fs/xfs/xfs_bmap.c 2006-10-13 12:13:43.498697319 +1000 @@ -684,7 +684,7 @@ xfs_bmap_add_extent( ASSERT(nblks <= da_old); if (nblks < da_old) xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, - (int)(da_old - nblks), rsvd); + (int64_t)(da_old - nblks), rsvd); } /* * Clear out the allocated field, done with it now in any case. @@ -1207,7 +1207,7 @@ xfs_bmap_add_extent_delay_real( diff = (int)(temp + temp2 - STARTBLOCKVAL(PREV.br_startblock) - (cur ? cur->bc_private.b.allocated : 0)); if (diff > 0 && - xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -diff, rsvd)) { + xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) { /* * Ick gross gag me with a spoon. */ @@ -1218,7 +1218,7 @@ xfs_bmap_add_extent_delay_real( diff--; if (!diff || !xfs_mod_incore_sb(ip->i_mount, - XFS_SBS_FDBLOCKS, -diff, rsvd)) + XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) break; } if (temp2) { @@ -1226,7 +1226,7 @@ xfs_bmap_add_extent_delay_real( diff--; if (!diff || !xfs_mod_incore_sb(ip->i_mount, - XFS_SBS_FDBLOCKS, -diff, rsvd)) + XFS_SBS_FDBLOCKS, -((int64_t)diff), rsvd)) break; } } @@ -2013,7 +2013,7 @@ xfs_bmap_add_extent_hole_delay( if (oldlen != newlen) { ASSERT(oldlen > newlen); xfs_mod_incore_sb(ip->i_mount, XFS_SBS_FDBLOCKS, - (int)(oldlen - newlen), rsvd); + (int64_t)(oldlen - newlen), rsvd); /* * Nothing to do for disk quota accounting here. */ @@ -3357,7 +3357,7 @@ xfs_bmap_del_extent( */ ASSERT(da_old >= da_new); if (da_old > da_new) - xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), + xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int64_t)(da_old - da_new), rsvd); if (delta) { /* DELTA: report the original extent. */ @@ -4927,28 +4927,28 @@ xfs_bmapi( if (rt) { error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - -(extsz), (flags & + -((int64_t)extsz), (flags & XFS_BMAPI_RSVBLOCKS)); } else { error = xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(alen), (flags & + -((int64_t)alen), (flags & XFS_BMAPI_RSVBLOCKS)); } if (!error) { error = xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - -(indlen), (flags & + -((int64_t)indlen), (flags & XFS_BMAPI_RSVBLOCKS)); if (error && rt) xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - extsz, (flags & + (int64_t)extsz, (flags & XFS_BMAPI_RSVBLOCKS)); else if (error) xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - alen, (flags & + (int64_t)alen, (flags & XFS_BMAPI_RSVBLOCKS)); } @@ -5614,13 +5614,13 @@ xfs_bunmapi( rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); do_div(rtexts, mp->m_sb.sb_rextsize); xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - (int)rtexts, rsvd); + (int64_t)rtexts, rsvd); (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_RTBLKS); } else { xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, - (int)del.br_blockcount, rsvd); + (int64_t)del.br_blockcount, rsvd); (void)XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Data type overflow in xfs_trans_unreserve_and_mod_sb 2006-10-13 6:13 ` David Chinner @ 2006-10-13 8:31 ` Shailendra Tripathi 0 siblings, 0 replies; 10+ messages in thread From: Shailendra Tripathi @ 2006-10-13 8:31 UTC (permalink / raw) To: David Chinner; +Cc: sandeen, xfs, Timothy Shimmin David Chinner wrote: >>Eric, you suggested specific 64 bit types - I think that's really the >>way to fix this, but it's a much bigger change... > > > Shailendra, here's a patch that passes XFSQA that changes this all to 64 bit > types. I've had to fix various type abuses that weren't obvious because gcc > fails to warn when you pass a uint into a function parameter that is declared > as int64_t..... > > I haven't tested the >2TB grow case yet, but it should work now > on both 32bit and 64 bit platforms with this patch. > > Is there anything I missed here in the conversion? > > Cheers, > > Dave. Looks ok to me, Dave. Thanks. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-10-13 8:35 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-09-23 13:27 largeio mount and performance impact Sebastian Brings 2006-09-23 16:34 ` Eric Sandeen 2006-09-24 13:41 ` Sebastian Brings 2006-09-24 13:47 ` Sebastian Brings 2006-09-25 8:38 ` Data type overflow in xfs_trans_unreserve_and_mod_sb Shailendra Tripathi 2006-09-25 14:32 ` Eric Sandeen 2006-09-25 14:52 ` Shailendra Tripathi 2006-10-11 5:25 ` David Chinner 2006-10-13 6:13 ` David Chinner 2006-10-13 8:31 ` Shailendra Tripathi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox