[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