[SSI] openssi/kernel/cluster/ssi/cfs cfs_subr.c, 1.29, 1.30 dir.c, 1.32, 1.33 file.c, 1.26, 1.27 inode.c, 1.67, 1.68

Roger Tsang <[email protected]> Wed, 15 Dec 2010 06:44:27 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv9659/cluster/ssi/cfs

Modified Files:
      Tag: OPENSSI-FC
	cfs_subr.c dir.c file.c inode.c 
Log Message:
cluster/ssi/cfs/cfs_subr.c (#ifdef CFS_ZAP_CACHES)
- cfs_update_attr: touch CFS_READTIME().

cluster/ssi/cfs/dir.c
- cfs_readdir_filler, uncached_readdir: no longer set CFS_INO_INVALID_ATIME c_flags since readlink() operation updates i_atime.

cluster/ssi/cfs/file.c
- do_setlk: skip cfs_zap_caches() since attributes were piggybacked during CFS flush.
- do_unlk, do_setlk: no need to clear the cache since token architecture guarantees cache coherency.

cluster/ssi/cfs/inode.c
- cfs_getattr: obtain CFS token before starting CFS SB thread.
- cfs_getattr: remove irrelevant CFS_SB_FSOP_START/DONE dance since this function is not the RPC operation.
- Fix [ ssic-linux-bugs 2010447 ] OpenSSI fails the glibc tst-atime test
  - cfs_getattr: force a getattr RPC operation if user cares about atime. (#ifdef CFS_ZAP_CACHES)
  - __cfs_revalidate_inode: do not do getattr too often. (#ifdef CFS_REVALIDATE_GETATTR)
  - cfs_fill_inode, __cfs_hpget: disable S_NOATIME i_flags since in cfs_getattr() we force a getattr.

cluster/ssi/cfs/inode.c (#ifdef CFS_SKIP)
- cfs_setattr: no need to flush data since token architecture guarantees cache coherency.

cluster/ssi/cfs/inode.c (#ifdef CFS_FILE_WRITE_LIVELOCK_FIX)
- cfs_setattr: test for ATTR_SIZE flag instead of down_write_trylock() on i_alloc_sem since our caller only acquires i_alloc_sem when ATTR_SIZE flag is set.
- cfs_setattr: no need to immediately re-acquire i_alloc_sem after re-acquiring i_sem since there is no race with DIO. CFS does not support DIO.

include/cluster/ssi/cfs/cfs_fs_i.h (#ifdef CFS_ZAP_CACHES)
- re-enable read_cache_jiffies field in cnode structure for CFS_READTIME() macro used in __cfs_revalidate_inode().

include/cluster/ssi/cfs/cfs_fs.h (#ifdef CFS_ZAP_CACHES)
- re-enable CFS_READTIME() preprocessor macro.

include/cluster/gen/cfs.x (#ifdef CFS_REVALIDATE_GETATTR)
- re-activate various code for CFS_PROTO->getattr().

include/linux/config.h
- re-enable CFS_REVALIDATE_GETATTR preprocessor directive to activate supporting code for CFS_PROTO->getattr().

 cluster/ssi/cfs/cfs_subr.c         |    2 
 cluster/ssi/cfs/dir.c              |    6 +
 cluster/ssi/cfs/file.c             |   15 ++
 cluster/ssi/cfs/inode.c            |  155 +++++++++++++----------------
 include/cluster/gen/cfs.x          |   12 +-
 include/cluster/ssi/cfs/cfs_fs.h   |    2 
 include/cluster/ssi/cfs/cfs_fs_i.h |    4 
 include/linux/config.h             |    4 
 8 files changed, 103 insertions(+), 97 deletions(-)


Index: inode.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/inode.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- inode.c	25 Oct 2010 05:26:47 -0000	1.67
+++ inode.c	15 Dec 2010 06:44:25 -0000	1.68
@@ -246,7 +246,9 @@
 	/* It's needed on 2.6.14 or we get an panic in clear_inode
 	 * (nr_pages != 0) when renaming - JH
 	 */
-	truncate_inode_pages(&inode->i_data, 0);
+	/* SSI_XXX: i_nlink race? Check generic_drop_inode() code path -RT */
+	if (inode->i_data.nrpages)
+		truncate_inode_pages(&inode->i_data, 0);
 
 	cfs_wb_all(inode);
 	/*
@@ -558,8 +560,10 @@
 	 * do this once. (We don't allow inodes to change types.)
 	 */
 	if (inode->i_state & I_NEW) {
+#ifdef CFS_SKIP
 		/* We don't yet support UPDATE_ATIME(), need to add atime token */
 		inode->i_flags |= S_NOATIME;
+#endif
 		CFS_FLAGS(inode) = 0;
 		inode->i_mode = fattr->cna_mode;
 		/* inode->i_ino = fattr->cna_ino; */ /* done in cfs_init_locked() */
@@ -796,12 +800,13 @@
 		/* Just install MHOLD */
 		cfstok_install_one (inode, CFSTOK_MHOLD, 0, 0, this_node,
 				    NON_RANGE, 0);
-
+#ifdef CFS_SKIP
 		/*
 		 * We don't yet support UPDATE_ATIME(), need to add atime
 		 * token.
 		 */
 		inode->i_flags |= S_NOATIME;
+#endif
 		CFS_FLAGS(inode) = 0;
 		inode->i_mode = hp->sct_ip->i_mode;
 		/* Why so? Because we want revalidate for devices/FIFOs, and
@@ -845,13 +850,18 @@
 #define CFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET)
 #endif
 
+/* Called with i_sem held */
 int
 cfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
 	int error, result;
-	int rwlocked;
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+	int rwlocked; /* non-zero: i_alloc_sem held */
 
+	/* Linux: called from notify_change() with down_write on i_alloc_sem */
+	rwlocked = (attr->ia_valid & ATTR_SIZE);
+#endif
 #ifdef CFS_SETATTR_LAZY
 	if (attr->ia_valid & ATTR_SIZE) {
 		if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
@@ -864,6 +874,7 @@
 		return 0;
 #endif
 
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
 	/* Avoid deadlock with fs/open.c:do_truncate
 	 *	-Roger
 	 *
@@ -873,9 +884,9 @@
 	 *                      (notify_change)
 	 *     ->CFSTOK_ATTR    (cfs_setattr)
 	 */
-	rwlocked = !down_write_trylock(&inode->i_alloc_sem);
-	up_write(&inode->i_alloc_sem);
-
+	if (rwlocked)
+		up_write(&inode->i_alloc_sem);
+#endif
 	/* SSI_XXX: We need to release the i_sem here, but we don't
 	 * have the ATTR_KILL_SUID and ATTR_KILL_SGID flags anymore.
 	 * We should be re-evaluating after getting tokens and
@@ -886,18 +897,13 @@
 	/* Hold ATTR token */
 	result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
 				CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, NULL);
-#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
 	down(&inode->i_sem);
-	if (rwlocked)
-		down_write(&inode->i_alloc_sem);
-#endif
 #ifdef CFSTOK_INTR
 	if (result == CFSTOK_INTERRUPTED) {
 #ifdef DEBUG
 		printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
 #endif
-#ifndef CFS_FILE_WRITE_LIVELOCK_FIX
-		down(&inode->i_sem);
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
 		if (rwlocked)
 			down_write(&inode->i_alloc_sem);
 #endif
@@ -907,6 +913,8 @@
 	SSI_ASSERT(result == CFSTOK_HELD);
 
 	cfs_begin_data_update(inode);
+#ifdef CFS_SKIP
+	/* SSI: No need to flush. Got token */
 #ifdef CFS_SETATTR_LAZY_FLUSH
         /* Write all dirty data if we're changing file permissions or size */
         if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) {
@@ -916,17 +924,10 @@
 #else
 	/* Flush early because the error case is not common */
 	error = cfs_wb_all(inode);
-#endif
-#ifndef CFS_FILE_WRITE_LIVELOCK_FIX
-	down(&inode->i_sem);
-	if (rwlocked)
-		down_write(&inode->i_alloc_sem);
-#endif
-
-#ifndef CFS_SETATTR_LAZY_FLUSH
 	if (error)
 		goto out;
 #endif
+#endif /* CFS_SKIP */
 
 	/* CFS can verify operation here, because we are holding tokens
 	 * and the inode is up to date.
@@ -938,12 +939,6 @@
 #ifndef CFS_SETATTR_LAZY_FLUSH
 	if (!S_ISREG(inode->i_mode))
 		attr->ia_valid &= ~ATTR_SIZE;
-#else
-	if (attr->ia_valid & ATTR_SIZE) {
-		/* SSI_XXX: will not refresh inode under writeback ? */
-		if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
-			attr->ia_valid &= ~ATTR_SIZE;
-	}
 #endif
 
 	if (attr->ia_valid & ATTR_SIZE) {
@@ -961,17 +956,21 @@
 	 * tossing local pages.  This is especially important for EXNFS.
 	 */
 	if (attr->ia_valid & ATTR_SIZE) {
-#ifndef CFS_SETATTR_LAZY_FLUSH
-#ifndef CFS_FILE_RW_NOLOCK
 #ifdef CFS_PARANOIA
+#ifndef CFS_SETATTR_LAZY_FLUSH
 		if (attr->ia_size != inode->i_size)
 			printk("cfs_setattr: attr=%Ld, inode=%Ld??\n",
 				(long long) attr->ia_size,
 				(long long)inode->i_size);
+#endif
 #endif /* CFS_PARANOIA */
+#ifdef SSI_NOTYET
+		/* No need to hold i_alloc_sem. We don't do DIO */
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+		BUG_ON(!rwlocked);
+		rwlocked = 0; /* don't acquire lock again */
+		down_write(&inode->i_alloc_sem);
 #endif
-#else
-		inode->i_size = attr->ia_size;
 #endif
 		/* Works even though i_size already set to desired size */
 		vmtruncate(inode, attr->ia_size);
@@ -981,6 +980,10 @@
 	cfs_end_data_update(inode);
 	/* Release token */
 	cfstok_relse(inode, CFSTOK_ATTR, CFSTOK_EXCL, NON_RANGE);
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+	if (rwlocked)
+		down_write(&inode->i_alloc_sem);
+#endif
 	return error;
 }
 
@@ -1110,20 +1113,12 @@
 int
 __cfs_revalidate_inode(struct inode *inode)
 {
-	int status = -ESTALE;
+	int status;
 
 	if (!inode || is_bad_inode(inode))
  		return -ESTALE;
-
-#ifdef SSI_CFS_SKIP
-	if (!CFS_SB_HARD_MIP(itocmi(inode)) && CFS_AT_SERVER(inode))
-		return 0;
-#endif
-
-#ifdef CFS_FILE_RW_NOLOCK
 	if (CFS_STALE(inode))
-		goto out_nowait;
-#endif
+ 		return -ESTALE;
 
 	/* cfs_wait_on_inode() */
 	LOCK_COND_LOCK(&itoc(inode)->c_statelock);
@@ -1145,13 +1140,17 @@
 	}
 	CFS_FLAGS(inode) |= CFS_INO_REVALIDATING;
 
-#ifndef CFS_FILE_RW_NOLOCK
-	status = 0;
-#else
 #ifdef CFS_REVALIDATE_GETATTR
+	/* Don't do getattr too often. Use CFS_MAXATTRTIMEO which is 60s */
+	if (!(CFS_FLAGS(inode) & CFS_INO_INVALID_ATIME) ||
+	    !time_after(jiffies, CFS_READTIME(inode) + 60*HZ)) {
+		status = 0;
+		goto skip_getattr;
+	}
 	UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+
 	status = CFS_PROTO(inode)->getattr(inode);
-	if (status != 0) {
+	if (unlikely(status != 0)) {
 		if (status == -EINVAL) {
 			cfs_zap_caches(inode);
 			LOCK_COND_LOCK(&itoc(inode)->c_statelock);
@@ -1162,10 +1161,10 @@
 		goto out;
 	}
 	LOCK_COND_LOCK(&itoc(inode)->c_statelock);
+skip_getattr:
 #else
-#error missing rpc op getattr
-#endif
-#endif /* CFS_FILE_RW_NOLOCK */
+	status = 0;
+#endif /* !CFS_REVALIDATE_GETATTR */
 
 	CFS_FLAGS(inode) &= ~(CFS_INO_INVALID_ATTR|CFS_INO_INVALID_ATIME);
 
@@ -1184,7 +1183,7 @@
 		CFS_FLAGS(inode) &= ~CFS_INO_INVALID_DATA;
 	}
 
-#if defined(CFS_FILE_RW_NOLOCK) && defined(CFS_REVALIDATE_GETATTR)
+#ifdef CFS_REVALIDATE_GETATTR
 out:
 #endif
 	CFS_FLAGS(inode) &= ~CFS_INO_REVALIDATING;
@@ -1275,73 +1274,57 @@
 cfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
 	struct inode *inode = dentry->d_inode;
-	struct cfs_server *server = itocmi(inode);
 	int	status;
-	int	result;
 #ifdef CFS_ZAP_CACHES
-#ifdef SSI_CFS_SKIP
 	int need_atime;
 #endif
-#endif
 
 	dfprintk(PAGECACHE, "CFS: revalidating (%x/%ld)\n",
 		inode->i_sb->s_dev, inode->i_ino);
 
-	CFS_SB_FSOP_START(server);
-sb_down_retry:
-	status = CFS_SB_CHECK(server);
-	if (status)
-		goto sb_error_check;
-
-	status = -ESTALE;
-	/* lock_kernel(); */
-	if (is_bad_inode(inode))
+	if (is_bad_inode(inode)) {
+		status = -ESTALE;
  		goto out_nowait;
+	}
 
-	result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
+	status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
 		CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
 #ifdef CFSTOK_INTR
-	if (result == CFSTOK_INTERRUPTED) {
+	if (status == CFSTOK_INTERRUPTED) {
 #ifdef DEBUG
 		printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
 #endif
 		status = -EINTR;
-		goto sb_error_check;
+ 		goto out_nowait;
 	}
 #endif
-	SSI_ASSERT(result == CFSTOK_HELD);
-#ifdef CFS_ZAP_CACHES
-#ifdef SSI_CFS_SKIP
-	LOCK_COND_LOCK(&itoc(inode)->c_statelock);
-	need_atime = CFS_FLAGS(inode) & CFS_INO_INVALID_ATIME;
-	UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+	SSI_ASSERT(status == CFSTOK_HELD);
 
-	if (__IS_FLG(inode, MS_NOATIME))
+#ifdef CFS_ZAP_CACHES
+	need_atime = 1;
+	if (IS_NOATIME(inode))
 		need_atime = 0;
-	else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode))
+	else if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
 		need_atime = 0;
 	/* We may force a getattr if the user cares about atime */
-	if (need_atime)
+	if (need_atime) {
+		LOCK_COND_LOCK(&itoc(inode)->c_statelock);
+		if (!(CFS_FLAGS(inode) & CFS_INO_INVALID_ATIME))
+			CFS_FLAGS(inode) |= CFS_INO_INVALID_ATIME;
+		UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
 		status = __cfs_revalidate_inode(inode);
-	else
-#endif
+	} else
 		status = cfs_revalidate_inode(inode);
 	if (!status)
-#endif
+#endif /* CFS_ZAP_CACHES */
 	generic_fillattr(inode, stat);
 
 	cfstok_relse(inode, CFSTOK_ATTR, CFSTOK_READ, NON_RANGE);
 
+out_nowait:
 	dfprintk(PAGECACHE, "CFS: (%x/%ld) revalidation complete\n",
 		inode->i_sb->s_dev, inode->i_ino);
 
- out_nowait:
-	/* unlock_kernel(); */
-
-sb_error_check:
-	if (CFS_SB_RETRY(server, status))
-		goto sb_down_retry;
-	CFS_SB_FSOP_DONE(server);
 	return status;
 }
 
@@ -1390,7 +1373,7 @@
 		goto out_changed;
 	}
 
-#if defined(CFS_ZAP_CACHES) && defined(CFS_FILE_RW_NOLOCK)
+#ifdef CFS_ZAP_CACHES
 	/*
 	 * Update the read time so we don't revalidate too often.
 	 */
@@ -1726,11 +1709,13 @@
 		memset(&cp->c_fh, 0, sizeof(cp->c_fh));
 		cp->c_flags = 0;
 		cp->c_hp = NULL;
-#if defined(CFS_ZAP_CACHES) && defined(CFS_FILE_RW_NOLOCK)
+#ifdef CFS_ZAP_CACHES
 		cp->read_cache_jiffies = 0;
+#ifdef CFS_FILE_RW_NOLOCK
 		cp->attrtimeo = 0;
 		cp->attrtimeo_timestamp = 0;
 #endif
+#endif /* CFS_ZAP_CACHES */
 		spin_lock_init(&cp->req_lock);
 		INIT_LIST_HEAD(&cp->dirty);
 		INIT_LIST_HEAD(&cp->commit);

Index: file.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/file.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- file.c	17 Dec 2009 06:43:50 -0000	1.26
+++ file.c	15 Dec 2010 06:44:25 -0000	1.27
@@ -814,6 +814,10 @@
 #ifdef LINUX_SSI_INTERRUPTIBLE
 	ssi_mask_signals(current, &oldset, 1);
 #endif
+#ifdef CFS_SKIP
+	/* No need to clear the cache since CFS token architecture
+	 * guarantees cache coherency.
+	 */
 #ifdef CFS_ZAP_CACHES
 	/*
 	 * Flush all pending writes before doing anything
@@ -831,6 +835,7 @@
 #endif
 	}
 #endif /* CFS_ZAP_CACHES */
+#endif /* CFS_SKIP */
 
 	CFS_SB_FSOP_START(mip);
 sb_down_retry:
@@ -899,6 +904,10 @@
 #ifdef LINUX_SSI_INTERRUPTIBLE
 	ssi_mask_signals(current, &oldset, 1);
 #endif
+#ifdef CFS_SKIP
+	/* No need to clear the cache since CFS token architecture
+	 * guarantees cache coherency.
+	 */
 #ifdef CFS_ZAP_CACHES
 	/*
 	 * Flush all pending writes before doing anything
@@ -923,6 +932,7 @@
 #endif
 	}
 #endif /* CFS_ZAP_CACHES */
+#endif /* CFS_SKIP */
 
 	CFS_SB_FSOP_START(mip);
 sb_down_retry:
@@ -996,6 +1006,10 @@
 		goto sb_down_retry;
 	CFS_SB_FSOP_DONE(mip);
 
+#ifdef CFS_SKIP
+	/* No need to clear the cache since CFS token architecture
+	 * guarantees cache coherency.
+	 */
 #ifdef CFS_ZAP_CACHES
 	/*
 	 * Make sure we clear the cache whenever we try to get the lock.
@@ -1017,6 +1031,7 @@
 #if defined(CFS_ZAP_CACHES) || defined(KERNEL2616_53)
 out:
 #endif
+#endif /* CFS_SKIP */
 #ifdef LINUX_SSI_INTERRUPTIBLE
 	ssi_unmask_signals(current, &oldset, 1);
 #endif

Index: cfs_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_subr.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- cfs_subr.c	17 Dec 2009 06:43:50 -0000	1.29
+++ cfs_subr.c	15 Dec 2010 06:44:25 -0000	1.30
@@ -1556,7 +1556,7 @@
 	svrcfstok_getiflags(hp, &flags);
 	cfstok_putiflags(ip, flags);
 
-#if defined(CFS_ZAP_CACHES) && defined(CFS_FILE_RW_NOLOCK)
+#ifdef CFS_ZAP_CACHES
 	LOCK_COND_LOCK(&itoc(ip)->c_statelock);
 	CFS_READTIME(ip) = jiffies;
 	UNLOCK_COND_LOCK(&itoc(ip)->c_statelock);

Index: dir.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/dir.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- dir.c	29 Aug 2010 17:42:36 -0000	1.32
+++ dir.c	15 Dec 2010 06:44:25 -0000	1.33
@@ -154,9 +154,12 @@
 	if (error < 0)
 		goto error;
 	SetPageUptodate(page);
+#ifdef CFS_SKIP
+	/* CFS piggybacks attributes */
 	LOCK_COND_LOCK(&itoc(inode)->c_statelock);
 	CFS_FLAGS(inode) |= CFS_INO_INVALID_ATIME;
 	UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+#endif
 	kunmap(page);
 	/* Ensure consistent page alignment of the data.
 	 * Note: assumes we have exclusive access to this mapping either
@@ -363,9 +366,12 @@
 	desc->error = CFS_PROTO(inode)->readdir(inode, desc->target,
 						desc->ptr,
 						PAGE_CACHE_SIZE);
+#ifdef CFS_SKIP
+	/* CFS piggybacks attributes */
 	LOCK_COND_LOCK(&itoc(inode)->c_statelock);
 	CFS_FLAGS(inode) |= CFS_INO_INVALID_ATIME;
 	UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+#endif
 	if (desc->error >= 0) {
 		if ((status = cfs_dir_decode(desc)) == 0)
 			desc->entry->prev_cookie = desc->target;


------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d