linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Tony Battersby" <tonyb@cybernetics.com>
To: <linux-fsdevel@vger.kernel.org>
Subject: [PATCH] [RFC] LBD fixes for Linux 2.6.10 [2/2]
Date: Tue, 11 Jan 2005 13:47:53 -0500	[thread overview]
Message-ID: <05Jan11.134911est.333426@cyborg.cybernetics.com> (raw)

Here is an "example" patch to fix some of the LBD issues with various
filesystems (ext3, reiserfs, xfs).  Unfortunately it looks like there
are many more LBD problems with the filesystems that I didn't fix, so I
am just calling this an "example" patch that shows some of what needs
to be done, but doesn't fix everything.  I am not a filesystem expert,
so I would prefer to leave it to others to do a full audit of all the
filesystems for LBD-compliance.  Specifically there are two things to
check:

1) Use sector_t rather than long or unsigned long for block numbers.
For auditing, just search for all occurrences of "long" in the filesystem
code and make sure it is not referring to a block number.

2) Make sure page->index is typecasted to either loff_t or sector_t
before shifting left (e.g. "(sector_t) page->index << (PAGE_CACHE_SHIFT -
s->s_blocksize_bits)").  For auditing, just search for "PAGE_CACHE_SHIFT".

It looks like XFS is pretty much OK with regards to LBD-compliance, but
ext3 and reiserfs are definitely not.  I haven't really investigated
other filesystems, so I don't know about any others.  If a filesystem
cannot be made LBD-compliant (whether for technical reasons or because
of lack of interest), could we at least make sure that the fact is
documented somewhere and that mkfs or mount fails if the partition
extends past sector 0xffffffff?

I haven't tested these changes at all, so please review and comment.

Anthony J. Battersby
Cybernetics


diff -urpN linux-2.6.10/fs/ext3/inode.c linux-2.6.10-lbd-fix/fs/ext3/inode.c
--- linux-2.6.10/fs/ext3/inode.c	Fri Dec 24 16:35:01 2004
+++ linux-2.6.10-lbd-fix/fs/ext3/inode.c	Wed Dec 29 10:38:13 2004
@@ -292,7 +292,7 @@ static inline int verify_chain(Indirect 
  */
 
 static int ext3_block_to_path(struct inode *inode,
-			long i_block, int offsets[4], int *boundary)
+			sector_t i_block, int offsets[4], int *boundary)
 {
 	int ptrs = EXT3_ADDR_PER_BLOCK(inode->i_sb);
 	int ptrs_bits = EXT3_ADDR_PER_BLOCK_BITS(inode->i_sb);
@@ -1595,7 +1595,8 @@ static int ext3_block_truncate_page(hand
 {
 	unsigned long index = from >> PAGE_CACHE_SHIFT;
 	unsigned offset = from & (PAGE_CACHE_SIZE-1);
-	unsigned blocksize, iblock, length, pos;
+	unsigned blocksize, length, pos;
+	sector_t iblock;
 	struct inode *inode = mapping->host;
 	struct buffer_head *bh;
 	int err;
@@ -1603,7 +1604,8 @@ static int ext3_block_truncate_page(hand
 
 	blocksize = inode->i_sb->s_blocksize;
 	length = blocksize - (offset & (blocksize - 1));
-	iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+	iblock = (sector_t) index <<
+	         (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
 
 	if (!page_has_buffers(page))
 		create_empty_buffers(page, blocksize, 0);
diff -urpN linux-2.6.10/fs/reiserfs/inode.c linux-2.6.10-lbd-fix/fs/reiserfs/inode.c
--- linux-2.6.10/fs/reiserfs/inode.c	Fri Dec 24 16:34:30 2004
+++ linux-2.6.10-lbd-fix/fs/reiserfs/inode.c	Wed Dec 29 10:28:21 2004
@@ -203,10 +203,10 @@ static inline void set_block_dev_mapped 
 // files which were created in the earlier version can not be longer,
 // than 2 gb
 //
-static int file_capable (struct inode * inode, long block)
+static int file_capable (struct inode * inode, sector_t block)
 {
     if (get_inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
-	block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
+	block < (1U << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
 	return 1;
 
     return 0;
@@ -244,7 +244,7 @@ static int file_capable (struct inode * 
 // Please improve the english/clarity in the comment above, as it is
 // hard to understand.
 
-static int _get_block_create_0 (struct inode * inode, long block,
+static int _get_block_create_0 (struct inode * inode, sector_t block,
 				 struct buffer_head * bh_result,
 				 int args)
 {
@@ -559,7 +559,7 @@ out:
 }
 
 static inline int _allocate_block(struct reiserfs_transaction_handle *th,
-			   long block,
+			   sector_t block,
                            struct inode *inode, 
 			   b_blocknr_t *allocated_block_nr, 
 			   struct path * path,
@@ -2063,7 +2063,7 @@ out:
 
 static int map_block_for_writepage(struct inode *inode, 
 			       struct buffer_head *bh_result, 
-                               unsigned long block) {
+                               sector_t block) {
     struct reiserfs_transaction_handle th ;
     int fs_gen ;
     struct item_head tmp_ih ;
@@ -2074,7 +2074,7 @@ static int map_block_for_writepage(struc
     INITIALIZE_PATH(path) ;
     int pos_in_item ;
     int jbegin_count = JOURNAL_PER_BALANCE_CNT ;
-    loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1 ;
+    loff_t byte_offset = ((loff_t) block << inode->i_sb->s_blocksize_bits) + 1 ;
     int retval ;
     int use_get_block = 0 ;
     int bytes_copied = 0 ;
@@ -2212,7 +2212,7 @@ static int reiserfs_write_full_page(stru
     struct inode *inode = page->mapping->host ;
     unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT ;
     int error = 0;
-    unsigned long block ;
+    sector_t block;
     struct buffer_head *head, *bh;
     int partial = 0 ;
     int nr = 0;
@@ -2252,7 +2252,7 @@ static int reiserfs_write_full_page(stru
 	kunmap_atomic(kaddr, KM_USER0) ;
     }
     bh = head ;
-    block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ;
+    block = (sector_t) page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ;
     /* first map all the buffers, logging any direct items we find */
     do {
 	if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
diff -urpN linux-2.6.10/fs/xfs/linux-2.6/xfs_aops.c linux-2.6.10-lbd-fix/fs/xfs/linux-2.6/xfs_aops.c
--- linux-2.6.10/fs/xfs/linux-2.6/xfs_aops.c	Fri Dec 24 16:35:28 2004
+++ linux-2.6.10-lbd-fix/fs/xfs/linux-2.6/xfs_aops.c	Wed Dec 29 10:33:25 2004
@@ -71,7 +71,7 @@ xfs_page_trace(
 	bhv_desc_t	*bdp;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 	loff_t		isize = i_size_read(inode);
-	loff_t		offset = page->index << PAGE_CACHE_SHIFT;
+	loff_t		offset = (loff_t) page->index << PAGE_CACHE_SHIFT;
 	int		delalloc = -1, unmapped = -1, unwritten = -1;
 
 	if (page_has_buffers(page))



             reply	other threads:[~2005-01-11 18:49 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-11 18:47 Tony Battersby [this message]
2005-01-13 18:43 ` [PATCH] [RFC] LBD fixes for Linux 2.6.10 [2/2] Matthew Wilcox
2005-01-13 18:54   ` Christoph Hellwig
2005-01-13 20:46   ` Tony Battersby

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=05Jan11.134911est.333426@cyborg.cybernetics.com \
    --to=tonyb@cybernetics.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).