SOURCES: ocfs2_2.6.22.14_fixes-20071127-1.patch (NEW) - Release 2....

matkor matkor at pld-linux.org
Sat Dec 29 15:12:31 CET 2007


Author: matkor                       Date: Sat Dec 29 14:12:31 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- Release 2. Added ocfs2 fixes.

---- Files affected:
SOURCES:
   ocfs2_2.6.22.14_fixes-20071127-1.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/ocfs2_2.6.22.14_fixes-20071127-1.patch
diff -u /dev/null SOURCES/ocfs2_2.6.22.14_fixes-20071127-1.patch:1.1
--- /dev/null	Sat Dec 29 15:12:31 2007
+++ SOURCES/ocfs2_2.6.22.14_fixes-20071127-1.patch	Sat Dec 29 15:12:26 2007
@@ -0,0 +1,272 @@
+diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
+index 0b229a9..27a7fef 100644
+--- a/fs/ocfs2/cluster/tcp.c
++++ b/fs/ocfs2/cluster/tcp.c
+@@ -859,17 +859,25 @@ static void o2net_sendpage(struct o2net_sock_container *sc,
+ 	struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
+ 	ssize_t ret;
+ 
+-
+-	mutex_lock(&sc->sc_send_lock);
+-	ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
+-					 virt_to_page(kmalloced_virt),
+-					 (long)kmalloced_virt & ~PAGE_MASK,
+-					 size, MSG_DONTWAIT);
+-	mutex_unlock(&sc->sc_send_lock);
+-	if (ret != size) {
++	while (1) {
++		mutex_lock(&sc->sc_send_lock);
++		ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
++						 virt_to_page(kmalloced_virt),
++						 (long)kmalloced_virt & ~PAGE_MASK,
++						 size, MSG_DONTWAIT);
++		mutex_unlock(&sc->sc_send_lock);
++		if (ret == size)
++			break;
++		if (ret == (ssize_t)-EAGAIN) {
++			mlog(0, "sendpage of size %zu to " SC_NODEF_FMT
++			     " returned EAGAIN\n", size, SC_NODEF_ARGS(sc));
++			cond_resched();
++			continue;
++		}
+ 		mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT 
+ 		     " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
+ 		o2net_ensure_shutdown(nn, sc, 0);
++		break;
+ 	}
+ }
+ 
+diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
+index e0cd750..fb72cd5 100644
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -186,6 +186,7 @@ int ocfs2_update_inode_atime(struct inode *inode,
+ 	int ret;
+ 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ 	handle_t *handle;
++	struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data;
+ 
+ 	mlog_entry_void();
+ 
+@@ -196,11 +197,27 @@ int ocfs2_update_inode_atime(struct inode *inode,
+ 		goto out;
+ 	}
+ 
++	ret = ocfs2_journal_access(handle, inode, bh,
++				   OCFS2_JOURNAL_ACCESS_WRITE);
++	if (ret) {
++		mlog_errno(ret);
++		goto out_commit;
++	}
++
++	/*
++	 * Don't use ocfs2_mark_inode_dirty() here as we don't always
++	 * have i_mutex to guard against concurrent changes to other
++	 * inode fields.
++	 */
+ 	inode->i_atime = CURRENT_TIME;
+-	ret = ocfs2_mark_inode_dirty(handle, inode, bh);
++	di->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
++	di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
++
++	ret = ocfs2_journal_dirty(handle, bh);
+ 	if (ret < 0)
+ 		mlog_errno(ret);
+ 
++out_commit:
+ 	ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
+ out:
+ 	mlog_exit(ret);
+@@ -976,6 +993,11 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
+ 	}
+ 
+ 	if (size_change && attr->ia_size != i_size_read(inode)) {
++		if (attr->ia_size > sb->s_maxbytes) {
++			status = -EFBIG;
++			goto bail_unlock;
++		}
++
+ 		if (i_size_read(inode) > attr->ia_size)
+ 			status = ocfs2_truncate_file(inode, bh, attr->ia_size);
+ 		else
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 36289e6..b22c169 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -1080,6 +1080,7 @@ static int ocfs2_rename(struct inode *old_dir,
+ 	struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
+ 						    // this is the 1st dirent bh
+ 	nlink_t old_dir_nlink = old_dir->i_nlink;
++	struct ocfs2_dinode *old_di;
+ 
+ 	/* At some point it might be nice to break this function up a
+ 	 * bit. */
+@@ -1354,7 +1355,20 @@ static int ocfs2_rename(struct inode *old_dir,
+ 
+ 	old_inode->i_ctime = CURRENT_TIME;
+ 	mark_inode_dirty(old_inode);
+-	ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
++
++	status = ocfs2_journal_access(handle, old_inode, old_inode_bh,
++				      OCFS2_JOURNAL_ACCESS_WRITE);
++	if (status >= 0) {
++		old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
++
++		old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec);
++		old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec);
++
++		status = ocfs2_journal_dirty(handle, old_inode_bh);
++		if (status < 0)
++			mlog_errno(status);
++	} else
++		mlog_errno(status);
+ 
+ 	/* now that the name has been added to new_dir, remove the old name */
+ 	status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
+diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
+index a860633..0367108 100644
+--- a/fs/ocfs2/ocfs2.h
++++ b/fs/ocfs2/ocfs2.h
+@@ -480,16 +480,16 @@ static inline unsigned int ocfs2_page_index_to_clusters(struct super_block *sb,
+ /*
+  * Find the 1st page index which covers the given clusters.
+  */
+-static inline unsigned long ocfs2_align_clusters_to_page_index(struct super_block *sb,
++static inline pgoff_t ocfs2_align_clusters_to_page_index(struct super_block *sb,
+ 							u32 clusters)
+ {
+ 	unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits;
+-	unsigned long index = clusters;
++        pgoff_t index = clusters;
+ 
+ 	if (PAGE_CACHE_SHIFT > cbits) {
+-		index = clusters >> (PAGE_CACHE_SHIFT - cbits);
++		index = (pgoff_t)clusters >> (PAGE_CACHE_SHIFT - cbits);
+ 	} else if (PAGE_CACHE_SHIFT < cbits) {
+-		index = clusters << (cbits - PAGE_CACHE_SHIFT);
++		index = (pgoff_t)clusters << (cbits - PAGE_CACHE_SHIFT);
+ 	}
+ 
+ 	return index;
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index 86b559c..07a4579 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -114,8 +114,6 @@ static void ocfs2_write_super(struct super_block *sb);
+ static struct inode *ocfs2_alloc_inode(struct super_block *sb);
+ static void ocfs2_destroy_inode(struct inode *inode);
+ 
+-static unsigned long long ocfs2_max_file_offset(unsigned int blockshift);
+-
+ static const struct super_operations ocfs2_sops = {
+ 	.statfs		= ocfs2_statfs,
+ 	.alloc_inode	= ocfs2_alloc_inode,
+@@ -315,39 +313,51 @@ static void ocfs2_destroy_inode(struct inode *inode)
+ 	kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
+ }
+ 
+-/* From xfs_super.c:xfs_max_file_offset
+- * Copyright (c) 2000-2004 Silicon Graphics, Inc.
+- */
+-static unsigned long long ocfs2_max_file_offset(unsigned int blockshift)
++static unsigned long long ocfs2_max_file_offset(unsigned int bbits,
++						unsigned int cbits)
+ {
+-	unsigned int pagefactor = 1;
+-	unsigned int bitshift = BITS_PER_LONG - 1;
+-
+-	/* Figure out maximum filesize, on Linux this can depend on
+-	 * the filesystem blocksize (on 32 bit platforms).
+-	 * __block_prepare_write does this in an [unsigned] long...
+-	 *      page->index << (PAGE_CACHE_SHIFT - bbits)
+-	 * So, for page sized blocks (4K on 32 bit platforms),
+-	 * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
+-	 *      (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
+-	 * but for smaller blocksizes it is less (bbits = log2 bsize).
+-	 * Note1: get_block_t takes a long (implicit cast from above)
+-	 * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
+-	 * can optionally convert the [unsigned] long from above into
+-	 * an [unsigned] long long.
++	unsigned int bytes = 1 << cbits;
++	unsigned int trim = bytes;
++	unsigned int bitshift = 32;
++
++	/*
++	 * i_size and all block offsets in ocfs2 are always 64 bits
++	 * wide. i_clusters is 32 bits, in cluster-sized units. So on
++	 * 64 bit platforms, cluster size will be the limiting factor.
+ 	 */
+ 
+ #if BITS_PER_LONG == 32
+ # if defined(CONFIG_LBD)
+ 	BUILD_BUG_ON(sizeof(sector_t) != 8);
+-	pagefactor = PAGE_CACHE_SIZE;
+-	bitshift = BITS_PER_LONG;
++	/*
++	 * We might be limited by page cache size.
++	 */
++	if (bytes > PAGE_CACHE_SIZE) {
++		bytes = PAGE_CACHE_SIZE;
++		trim = 1;
++		/*
++		 * Shift by 31 here so that we don't get larger than
++		 * MAX_LFS_FILESIZE
++		 */
++		bitshift = 31;
++	}
+ # else
+-	pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
++	/*
++	 * We are limited by the size of sector_t. Use block size, as
++	 * that's what we expose to the VFS.
++	 */
++	bytes = 1 << bbits;
++	trim = 1;
++	bitshift = 31;
+ # endif
+ #endif
+ 
+-	return (((unsigned long long)pagefactor) << bitshift) - 1;
++	/*
++	 * Trim by a whole cluster when we can actually approach the
++	 * on-disk limits. Otherwise we can overflow i_clusters when
++	 * an extent start is at the max offset.
++	 */
++	return (((unsigned long long)bytes) << bitshift) - trim;
+ }
+ 
+ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
+@@ -1244,8 +1254,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
+ 				  int sector_size)
+ {
+ 	int status = 0;
+-	int i;
+-	struct ocfs2_dinode *di = NULL;
++	int i, cbits, bbits;
++	struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
+ 	struct inode *inode = NULL;
+ 	struct buffer_head *bitmap_bh = NULL;
+ 	struct ocfs2_journal *journal;
+@@ -1264,9 +1274,12 @@ static int ocfs2_initialize_super(struct super_block *sb,
+ 	sb->s_fs_info = osb;
+ 	sb->s_op = &ocfs2_sops;
+ 	sb->s_export_op = &ocfs2_export_ops;
++	sb->s_time_gran = 1;
+ 	sb->s_flags |= MS_NOATIME;
+ 	/* this is needed to support O_LARGEFILE */
+-	sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits);
++	cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);
++	bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
++	sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
+ 
+ 	osb->sb = sb;
+ 	/* Save off for ocfs2_rw_direct */
+@@ -1326,8 +1339,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
+ 		goto bail;
+ 	}
+ 
+-	di = (struct ocfs2_dinode *)bh->b_data;
+-
+ 	osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
+ 	if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
+ 		mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
================================================================


More information about the pld-cvs-commit mailing list