[SSI] openssi/kernel/cluster/ssi/cfs cfs_ipcshm.c, 1.16, 1.17 cfs_server.c, 1.14, 1.15 cfs_subr.c, 1.23, 1.24 cfs_svc.c, 1.17, 1.18 cfsproc.c, 1.28, 1.29 cfstok.c, 1.19, 1.20 dir.c, 1.23, 1.24 file.c, 1.21, 1.22 inode.c, 1.56, 1.57 proc.c, 1.18, 1.19 read.c, 1.19, 1.20 svrcfs.c, 1.17, 1.18 symlink.c, 1.10, 1.11 vfs.c, 1.27, 1.28 write.c, 1.35, 1.36
Roger Tsang <[email protected]>
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv8553/cluster/ssi/cfs
Modified Files:
Tag: OPENSSI-FC
cfs_ipcshm.c cfs_server.c cfs_subr.c cfs_svc.c cfsproc.c
cfstok.c dir.c file.c inode.c proc.c read.c svrcfs.c symlink.c
vfs.c write.c
Log Message:
Bug fixes and enhancements. (see ChangeLog)
Index: cfs_ipcshm.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_ipcshm.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cfs_ipcshm.c 22 Apr 2005 02:09:15 -0000 1.16
+++ cfs_ipcshm.c 3 Feb 2009 06:18:12 -0000 1.17
@@ -67,8 +67,8 @@
key_t key,
int shmflg)
{
- struct shmid_kernel_svr *svr_shm = NULL;
- struct dentry *de = NULL;
+ struct shmid_kernel_svr *svr_shm;
+ struct dentry *de;
nsc_nodelist_t *nl;
int err = 0;
@@ -95,6 +95,11 @@
svr_shm->shm_nodelist = nl;
svr_shm->shm_svr =(struct svrcfstok *)makehp(cfs_shm_sb,
ssidev_get_s_ssidev(shm_mnt->mnt_sb, FALSE),de);
+ SSI_ASSERT(svr_shm->shm_svr);
+#ifdef CFS_IPCSHM_DENTRY
+ if (!svr_shm->shm_svr->sct_dp)
+ svr_shm->shm_svr->sct_dp = dget(de);
+#endif
if (shm_svr_addid(svr_shm) < 0) {
printk("failed to add shm svr\n");
HASH_RELE(svr_shm->shm_svr);
@@ -137,7 +142,11 @@
de->d_sb = ip->i_sb;
de->d_parent = cfs_shm_sb->s_root;
d_instantiate(de, ip);
+#ifdef CFS_IPCSHM_DENTRY
+ d_rehash(de);
+#else
d_rehash(shmsvr->shm_svr->sct_dp);
+#endif
return de;
}
else {
@@ -266,7 +275,9 @@
void
shm_svr_cleanup(struct shmid_kernel_svr *shmsvr)
{
+#ifndef CFS_IPCSHM_DENTRY
d_drop(shmsvr->shm_svr->sct_dp);
+#endif
HASH_RELE(shmsvr->shm_svr);
}
@@ -301,17 +312,8 @@
struct inode *
shm_svr_get_inode(int id)
{
- struct inode *i;
- struct svrcfstok *hp;
- struct shmid_kernel_svr *shmsvr;
-
- shmsvr = (struct shmid_kernel_svr *)shm_svr_get(id);
- if (!shmsvr)
- return NULL;
- hp = shmsvr->shm_svr;
- i = (struct inode *)hp->sct_ip;
-
- return i;
+ struct shmid_kernel_svr *shmsvr = shm_svr_get(id);
+ return shmsvr ? shmsvr->shm_svr->sct_ip : NULL;
}
Index: cfs_server.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_server.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- cfs_server.c 10 Oct 2008 08:10:31 -0000 1.14
+++ cfs_server.c 3 Feb 2009 06:18:12 -0000 1.15
@@ -473,6 +473,22 @@
else {
nlp = NSC_NODELIST_ALLOC();
if (nlp != NULL) {
+ if ((rootip = sb->s_root->d_inode)) {
+ igrab(rootip);
+ roothp = itoc(rootip)->c_hp;
+ if (roothp) {
+ HASH_HOLD(roothp);
+ *nlp = svrcfstok_get_mholdlist(roothp);
+ HASH_RELE(roothp);
+ } else
+ error = -EBUSY;
+ iput(rootip);
+ } else {
+ roothp = NULL;
+ error = -EBUSY;
+ }
+#ifdef SSI_SKIP
+/* Do not remove. Keep for reference */
/* SSI_XXX: Is this safe without locking? */
/* CTABLE_SHR_LOCK(); */
rootip = sb->s_root->d_inode;
@@ -484,15 +500,14 @@
roothp = itoc(rootip)->c_hp;
if (roothp != NULL) {
HASH_HOLD(roothp);
- LOCK_LOCK(&roothp->sct_tcblock);
*nlp = svrcfstok_get_mholdlist(roothp);
- UNLOCK_LOCK(&roothp->sct_tcblock);
HASH_RELE(roothp);
}
else
error = -EBUSY;
if (rootip != NULL)
iput(rootip);
+#endif
}
}
/* Success? */
@@ -704,7 +719,6 @@
return 0;
droot = sbtocmi(sb)->mi_pfs_sb->s_root;
- dget(droot); /* needed? */
down(&(droot->d_inode->i_sem));
@@ -718,6 +732,7 @@
ddir = lookup_one_len(CFS_UNLINKDIR, droot, strlen(CFS_UNLINKDIR));
if (IS_ERR(ddir)) {
error = PTR_ERR(ddir);
+ ddir = NULL;
goto done;
}
up(&(droot->d_inode->i_sem));
@@ -884,7 +899,6 @@
fput(filp);
if (dir_buf)
kfree(dir_buf);
- dput(droot); /* needed? */
if (ddir)
dput(ddir);
if (dhp)
Index: inode.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/inode.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- inode.c 10 Oct 2008 08:10:31 -0000 1.56
+++ inode.c 3 Feb 2009 06:18:12 -0000 1.57
@@ -72,7 +72,12 @@
#define CFS_PARANOIA 1
+#ifdef RCU_CFSTOK_TABLE
+extern void svrcfstok_init(void);
+#endif
+#ifdef SSI_XXX
void svrcfstok_deinit(void);
+#endif
int ics_cfs_svc_init(void);
void cfs_start_daemon(void);
void cfstok_param_init (void);
@@ -458,18 +463,18 @@
cfs_zap_caches(struct inode *inode)
{
#ifdef CFS_ZAP_CACHES
+ int mode = inode->i_mode;
+
LOCK_COND_LOCK(&itoc(inode)->c_statelock);
#ifdef CFS_FILE_RW_NOLOCK
CFS_ATTRTIMEO(inode) = CFS_MINATTRTIMEO(inode);
CFS_ATTRTIMEO_UPDATE(inode) = jiffies;
#endif
-
- /* Mark the attribute cache for revalidation */
- CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR;
- /* Directories and symlinks: invalidate page cache too */
- if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
- CFS_FLAGS(inode) |= CFS_INO_INVALID_DATA;
+ if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
+ CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR | CFS_INO_INVALID_DATA | CFS_INO_INVALID_ACCESS;
+ else
+ CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR | CFS_INO_INVALID_ACCESS;
UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
#else
@@ -598,7 +603,7 @@
#ifdef SSI_XXX
/* SSI_XXX: This may be needed instead ? */
if (memcmp (itocfh(inode), &(desc->cdrok->cdrok_fhandle),
- sizeof (cfhandle_t) != 0)
+ sizeof (cfhandle_t) != 0))
return 0;
#endif /* SSI_XXX */
} else {
@@ -607,7 +612,7 @@
#ifdef SSI_XXX
/* SSI_XXX: This may be needed instead ? */
if (memcpy(itocfh(inode), &(desc->hp->sct_fh),
- sizeof (cfhandle_t) != 0)
+ sizeof (cfhandle_t) != 0))
return 0;
#endif /* SSI_XXX */
}
@@ -642,7 +647,7 @@
memcpy(itocfh(inode), &(desc->hp->sct_fh), sizeof (cfhandle_t));
itoc(inode)->c_hp = desc->hp;
- HASH_HOLD(itoc(inode)->c_hp);
+ HASH_HOLD(desc->hp);
itoc(inode)->c_locknumber = (void *) &(desc->hp->sct_mhold);
@@ -801,9 +806,7 @@
{
struct inode *inode = dentry->d_inode;
int error, result;
-#ifndef SSI_RECURSIVE_SEMAPHORE
int rwlocked;
-#endif
#ifdef CFS_SETATTR_LAZY
if (attr->ia_valid & ATTR_SIZE) {
@@ -817,7 +820,6 @@
return 0;
#endif
-#ifndef SSI_RECURSIVE_SEMAPHORE
/* Avoid deadlock with fs/open.c:do_truncate
* -Roger
*
@@ -836,12 +838,30 @@
* reaquiring i_sem.
*/
up(&inode->i_sem);
-#endif
/* 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_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+#ifndef CFS_FILE_WRITE_LIVELOCK_FIX
+ down(&inode->i_sem);
+ if (rwlocked)
+ down_write(&inode->i_alloc_sem);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif /* !CFSTOK_INTR */
cfs_begin_data_update(inode);
#ifdef CFS_SETATTR_LAZY_FLUSH
@@ -855,7 +875,7 @@
/* Flush early because the error case is not common */
error = cfs_wb_all(inode);
#endif
-#ifndef SSI_RECURSIVE_SEMAPHORE
+#ifndef CFS_FILE_WRITE_LIVELOCK_FIX
down(&inode->i_sem);
if (rwlocked)
down_write(&inode->i_alloc_sem);
@@ -1082,7 +1102,7 @@
if (CFS_FLAGS(inode) & CFS_INO_INVALID_DATA) {
UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
- if (S_ISREG(inode->i_mode) && inode->i_mapping->nrpages) {
+ if (S_ISREG(inode->i_mode) && inode->i_mapping->nrpages) {
unmap_mapping_range(inode->i_mapping, 0, 0, 0);
if (!filemap_write_and_wait(inode->i_mapping))
(void)cfs_wb_all(inode);
@@ -1187,6 +1207,11 @@
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);
@@ -1204,10 +1229,22 @@
result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ status = -EINTR;
+ goto sb_error_check;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
#ifdef CFS_ZAP_CACHES
-#if SSI_EXNFS
- int need_atime = CFS_FLAGS(inode) & CFS_INO_INVALID_ATIME;
+#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);
if (__IS_FLG(inode, MS_NOATIME))
need_atime = 0;
@@ -1301,12 +1338,20 @@
#ifdef CLMS_PREEMPT
cur_isize = i_size_read(inode);
#ifdef CFS_ZAP_CACHES
- if (cur_isize != new_isize
- && (!cfs_have_writebacks(inode) || new_isize > cur_isize)) {
- i_size_write(inode, new_isize);
- LOCK_COND_LOCK(&itoc(inode)->c_statelock);
- CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR|CFS_INO_INVALID_DATA;
- UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ if (cur_isize != new_isize) {
+ if (S_ISREG(inode->i_mode) && cfs_have_writebacks(inode)) {
+ if (new_isize > cur_isize) {
+ i_size_write(inode, new_isize);
+ LOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR|CFS_INO_INVALID_DATA;
+ UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ }
+ } else {
+ i_size_write(inode, new_isize);
+ LOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR|CFS_INO_INVALID_DATA;
+ UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ }
}
#else
if (cfs_have_writebacks(inode) && new_isize < cur_isize)
@@ -1336,9 +1381,11 @@
#ifdef CFS_DEBUG_VERBOSE
printk(KERN_DEBUG "CFS: mtime change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino);
#endif
- LOCK_COND_LOCK(&itoc(inode)->c_statelock);
- CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR|CFS_INO_INVALID_DATA;
- UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ if (!cfs_have_writebacks(inode)) {
+ LOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR|CFS_INO_INVALID_DATA;
+ UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ }
}
#endif /* CFS_ZAP_CACHES */
@@ -1353,12 +1400,24 @@
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
inode->i_rdev = fattr->cna_rdev;
+#ifndef CFS_ZAP_CACHES
itoc(inode)->c_vn = fattr->cna_vn;
+#else
+ if (itoc(inode)->c_vn != fattr->cna_vn) {
+ itoc(inode)->c_vn = fattr->cna_vn;
+ if (!cfs_have_writebacks(inode)) {
+ LOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ CFS_FLAGS(inode) |= CFS_INO_INVALID_ATTR|CFS_INO_INVALID_DATA|CFS_INO_INVALID_ACCESS;
+ UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
+ }
+ }
+#endif
inode->i_generation = fattr->cna_generation;
cfstok_putiflags(inode, fattr->cna_flags);
-#if defined(CFS_ZAP_CACHES) && defined(CFS_FILE_RW_NOLOCK)
+#if defined(CFS_ZAP_CACHES)
+#if defined(CFS_FILE_RW_NOLOCK)
/* Update attrtimeo value if we're out of the unstable period */
LOCK_COND_LOCK(&itoc(inode)->c_statelock);
if (CFS_FLAGS(inode) & CFS_INO_INVALID_ATTR) {
@@ -1370,7 +1429,7 @@
CFS_ATTRTIMEO_UPDATE(inode) = jiffies;
}
UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
-#ifdef SSI_EXNFS
+#endif
/* Don't invalidate the data if we were to blame */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
|| S_ISLNK(inode->i_mode))) {
@@ -1379,7 +1438,6 @@
UNLOCK_COND_LOCK(&itoc(inode)->c_statelock);
}
#endif
-#endif
return 0;
@@ -1509,21 +1567,48 @@
tokseq_t *cfs_tsp;
int cfs_initialized;
+#ifdef CFSTOK_KMEM_CACHE
+extern void cfstokhold_init(void);
+extern void cfs_delrel_init(void);
+#else
+extern SPIN_LOCK_T (ctokhold_free_lock);
+extern SPIN_LOCK_T (dr_free_lock);
+#endif
+#ifdef SVRCFS_KMEM_CACHE
+extern void hlist_cache_init(void);
+#else
+extern SPIN_LOCK_T (hlist_t_free_lock);
+#endif
+#ifdef CLITOK_KMEM_CACHE
+extern void nrreq_init(void);
+extern void nrrevoke_init(void);
+#else
extern SPIN_LOCK_T (nrreq_free_lock);
extern SPIN_LOCK_T (nrrev_free_lock);
+#endif
+#ifdef SVRTOK_KMEM_CACHE
+extern void node_ent_init(void);
+extern void nrwant_init(void);
+#else
extern SPIN_LOCK_T (node_free_lock);
extern SPIN_LOCK_T (nrwant_free_lock);
-extern SPIN_LOCK_T (ctokhold_free_lock);
-extern SPIN_LOCK_T (dr_free_lock);
+#endif
+#ifdef MHSVRTOK_KMEM_CACHE
+extern void mhnode_init(void);
+#else
+extern SPIN_LOCK_T mhnode_free_lock;
+#endif
extern SOFTIRQ_SPIN_LOCK_T (dr_list_lock);
-extern SPIN_LOCK_T (hlist_t_free_lock);
#ifdef SSI_CFS_POLICY
extern SPIN_LOCK_T (contention_free_lock);
extern SPIN_LOCK_T (condata_node_free_lock);
#endif /* SSI_CFS_POLICY */
-extern SPIN_LOCK_T mhnode_free_lock;
+#ifdef RCU_CFSTOK_TABLE
+extern spinlock_t svrcfstok_table_lock;
+#else
extern LOCK_T svrcfstok_table_lock;
+#endif
#ifdef SSI_EXNFS
extern LOCK_T exnfs_svr_lock;
extern LOCK_T exnfs_svr_start_lock;
@@ -1589,6 +1674,10 @@
#endif
cp->c_hp = NULL;
INIT_CONDITION(&(cp->c_cxlock));
+#ifdef CFSTOKHOLD_LINUX_LIST
+ for(idx = 0; idx < CFSTOK_NTOKS; idx++)
+ INIT_LIST_HEAD(&cp->c_hlist[idx]);
+#endif
INIT_COND_LOCK(&(cp->c_statelock));
INIT_LOCK(&(cp->c_tcblock));
for (idx = 0 ; idx < CFS_MAX_LISTS ; idx++)
@@ -1627,10 +1716,13 @@
{
cfs_init_inodecache();
+#ifdef RCU_CFSTOK_TABLE
+ svrcfstok_init();
+#endif
cfstok_param_init();
/* Initialize Message Support code */
- msgsup_init();
+ msgsup_init(); /* msgsup_msg_cache, msgsup_id_cache */
/* Initialize Range token code */
cliglue_global_init();
@@ -1655,24 +1747,39 @@
/*
* initialize global fast spin locks
*/
+#ifndef CFSTOK_KMEM_CACHE
+ INIT_SPIN_LOCK(&ctokhold_free_lock);
+ INIT_SPIN_LOCK(&dr_free_lock);
+#endif
+#ifndef SVRCFS_KMEM_CACHE
+ INIT_SPIN_LOCK(&hlist_t_free_lock);
+#endif
+#ifndef CLITOK_KMEM_CACHE
INIT_SPIN_LOCK(&nrreq_free_lock);
INIT_SPIN_LOCK(&nrrev_free_lock);
+#endif
+#ifndef SVRTOK_KMEM_CACHE
INIT_SPIN_LOCK(&node_free_lock);
- INIT_SPIN_LOCK(&mhnode_free_lock);
INIT_SPIN_LOCK(&nrwant_free_lock);
- INIT_SPIN_LOCK(&ctokhold_free_lock);
- INIT_SPIN_LOCK(&dr_free_lock);
+#endif
+#ifndef MHSVRTOK_KMEM_CACHE
+ INIT_SPIN_LOCK(&mhnode_free_lock);
+#endif
INIT_SOFTIRQ_SPIN_LOCK(&dr_list_lock);
- INIT_SPIN_LOCK(&hlist_t_free_lock);
#ifdef SSI_CFS_POLICY
INIT_SPIN_LOCK(&contention_free_lock);
INIT_SPIN_LOCK(&condata_node_free_lock);
#endif
+#ifdef RCU_CFSTOK_TABLE
+ spin_lock_init(&svrcfstok_table_lock);
+#endif
/*
* initialize global sleep locks
*/
+#ifndef RCU_CFSTOK_TABLE
INIT_LOCK(&svrcfstok_table_lock);
+#endif
#ifdef SSI_EXNFS
INIT_LOCK(&exnfs_svr_lock);
INIT_LOCK(&exnfs_svr_start_lock);
@@ -1698,17 +1805,45 @@
sb_nblks = (struct sb_nblks *)kmem_zalloc(MAX_SB_NBLKS_ENTRY * sizeof(struct sb_nblks), KM_SLEEP);
#endif
+ /*
+ * initialize token caches
+ */
+#ifdef CFSTOK_KMEM_CACHE
+ cfstokhold_init(); /* cfstok_cache */
+ cfs_delrel_init(); /* cfsdr_cache */
+#else
/* SSI_XXX: What value of seeks here? dbz */
set_shrinker(DEFAULT_SEEKS, cfstok_free_memory);
set_shrinker(DEFAULT_SEEKS, cfsdr_free_memory);
+#endif
+#ifdef SVRCFS_KMEM_CACHE
+ hlist_cache_init(); /* svrhl_cache */
+#else
set_shrinker(DEFAULT_SEEKS, svrhl_free_memory);
+#endif
+#ifdef CLITOK_KMEM_CACHE
+ nrreq_init(); /* clitok_req_cache */
+ nrrevoke_init(); /* clitok_rev_cache */
+#else
set_shrinker(DEFAULT_SEEKS, clitok_req_free_memory);
set_shrinker(DEFAULT_SEEKS, clitok_rev_free_memory);
+#endif
+#ifdef SVRTOK_KMEM_CACHE
+ node_ent_init(); /* svrtok_nd_cache */
+ nrwant_init(); /* svrtok_wt_cache */
+#else
set_shrinker(DEFAULT_SEEKS, svrtok_nd_free_memory);
set_shrinker(DEFAULT_SEEKS, svrtok_wt_free_memory);
+#endif
+#ifdef MHSVRTOK_KMEM_CACHE
+ mhnode_init(); /* mhsvrtok_cache */
+#else
set_shrinker(DEFAULT_SEEKS, mhsvrtok_free_memory);
+#endif
+#ifndef RCU_MSGSUP
set_shrinker(DEFAULT_SEEKS, msgsup_msg_free_memory);
set_shrinker(DEFAULT_SEEKS, msgsup_id_free_memory);
+#endif
return;
}
Index: cfs_svc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_svc.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cfs_svc.c 10 Oct 2008 08:10:31 -0000 1.17
+++ cfs_svc.c 3 Feb 2009 06:18:12 -0000 1.18
@@ -685,6 +685,10 @@
int i;
int error;
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ if (!vec_len)
+ return 0;
+#endif
*vec = __vec = kmalloc_nofail(sizeof(struct kvec) * vec_len);
for (i = 0; i < vec_len; i++, __vec++) {
@@ -698,7 +702,7 @@
return 0;
}
-#endif
+#endif /* CFS_PAGEVEC */
/*
* param IN:XDR struct cfswriteargs *
Index: write.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/write.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- write.c 10 Oct 2008 08:10:32 -0000 1.35
+++ write.c 3 Feb 2009 06:18:12 -0000 1.36
@@ -438,6 +438,9 @@
pgoff_t end;
unsigned int npages = 0;
#endif
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+ int flushing = sem_flushing(&inode->i_sem);
+#endif
err = generic_writepages(mapping, wbc);
if (err)
@@ -445,8 +448,14 @@
#ifdef CFS_WRITEPAGES_AT_SVR_SKIP_BDI
/* Don't interfere with backing device's request queue. */
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+ while (!flushing &&
+ test_and_set_bit(BDI_cfs_write_congested,
+ &bdi->state) != 0) {
+#else
while (test_and_set_bit(BDI_cfs_write_congested,
&bdi->state) != 0) {
+#endif
#else
while (test_and_set_bit(BDI_write_congested,
&bdi->state) != 0) {
@@ -497,6 +506,10 @@
}
out:
#ifdef CFS_WRITEPAGES_AT_SVR_SKIP_BDI
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+ if (flushing)
+ return err;
+#endif
smp_mb__before_clear_bit();
clear_bit(BDI_cfs_write_congested, &bdi->state);
smp_mb__after_clear_bit();
@@ -759,6 +772,28 @@
DEFINE_WAIT(wait);
int ret = 0;
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+ /* RT: [ ssic-linux-Bugs-686748 ] Filesystem stacking deadlock. Part 2.
+ *
+ * Deadlock wait on bit:
+ * (pdflush)
+ * ...
+ * BDI_cfs_write_congested (cfs_writepages)
+ * ...
+ * (generic_file_buffered_write)
+ * ...
+ * (alloc_pages)
+ * ...
+ * (shrink_caches)
+ * ...
+ * (cfs_writepage)
+ * ...
+ * cfs_write_congestion (cfs_wait_on_write_congestion)
+ */
+ if (sem_flushing(&mapping->host->i_sem))
+ return 0;
+#endif
+
might_sleep();
#ifdef CFS_WRITEPAGES_AT_SVR_SKIP_BDI
@@ -1013,7 +1048,11 @@
*/
static void cfs_async_handler_write(void *args)
{
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ struct cfs_write_data *data = (struct cfs_write_data *)args;
+#else
struct cfs_write_data *data = *(struct cfs_write_data **)args;
+#endif
struct inode *inode = data->inode;
int stable = data->stable;
int status;
@@ -1271,9 +1310,21 @@
#else
if (async) {
#endif
+#ifdef NSC_ASYNC_SLAB_NOFS__FLAG
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ if (nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_write,
+ data, sizeof(*data),
+ NSC_ASYNC_SLEEP | NSC_ASYNC_SLAB_NOFS)) {
+#else
+ if (nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_write,
+ &data, sizeof(data),
+ NSC_ASYNC_SLEEP | NSC_ASYNC_SLAB_NOFS)) {
+#endif
+#else
if (nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_write,
&data, sizeof(struct cfs_write_data *),
NSC_ASYNC_SLEEP)) {
+#endif
while (!list_empty(&data->pages)) {
req = cfs_list_entry(data->pages.next);
@@ -1291,7 +1342,11 @@
return -ENOMEM;
}
} else
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ cfs_async_handler_write(data);
+#else
cfs_async_handler_write(&data);
+#endif
#ifdef NSC_INHERIT_USER_NICE
if (how & FLUSH_LOWPRI)
set_user_nice(current, old_nice);
@@ -1349,7 +1404,11 @@
*/
static void cfs_async_handler_commit(void *args)
{
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ struct cfs_write_data *data = (struct cfs_write_data *)args;
+#else
struct cfs_write_data *data = *(struct cfs_write_data **)args;
+#endif
int status = 0;
unsigned int res = 0;
@@ -1555,9 +1614,21 @@
#else
if (async) {
#endif
+#ifdef NSC_ASYNC_SLAB_NOFS__FLAG
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ if (nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_commit,
+ data, sizeof(*data),
+ NSC_ASYNC_SLEEP | NSC_ASYNC_SLAB_NOFS)) {
+#else
+ if (nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_commit,
+ &data, sizeof(struct cfs_write_data *),
+ NSC_ASYNC_SLEEP | NSC_ASYNC_SLAB_NOFS)) {
+#endif
+#else
if (nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_commit,
&data, sizeof(struct cfs_write_data *),
NSC_ASYNC_SLEEP)) {
+#endif
while (!list_empty(&data->pages)) {
req = cfs_list_entry(data->pages.next);
@@ -1573,7 +1644,11 @@
return -ENOMEM;
}
} else
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ cfs_async_handler_commit(data);
+#else
cfs_async_handler_commit(&data);
+#endif
#ifdef NSC_INHERIT_USER_NICE
if (how & FLUSH_LOWPRI)
set_user_nice(current, old_nice);
Index: file.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/file.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- file.c 10 Oct 2008 08:10:31 -0000 1.21
+++ file.c 3 Feb 2009 06:18:12 -0000 1.22
@@ -124,8 +124,23 @@
* field.
*/
if (origin == 2)
+#ifdef CFSTOK_INTR
+ {
+ int status;
+
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
+ CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+ if (status != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+ }
+#else
(void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+#endif
/* SSI_XXX: Subtle diff with default_llseek() & generic_file_llseek() */
result = remote_llseek(file, offset, origin);
@@ -152,12 +167,22 @@
/* Avoid invalidate_inode_pages race */
#ifdef SSI_CFSTOK_SU
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_SU,
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_SU,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#else
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#endif
+#ifdef CFSTOK_INTR
+ if (status != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
+ SSI_ASSERT(status == CFSTOK_HELD);
+#endif
/* Ensure that data+attribute caches are up to date after close() */
status = cfs_wb_all(inode);
@@ -203,7 +228,7 @@
#ifndef CFS_FILE_RW_NOLOCK
cfstok_hl_init(&held);
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
+ result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, &held);
/* SSI_XXX: ATIME?
@@ -218,10 +243,20 @@
rnd_len = count + (*ppos & (PAGE_CACHE_SIZE - 1));
rnd_len = ((rnd_len + (PAGE_CACHE_SIZE - 1)) >> PAGE_CACHE_SHIFT)
<< PAGE_CACHE_SHIFT;
- (void)cfstok_req(inode, CFSTOK_DATA, CFSTOK_READ,
+ result = cfstok_req(inode, CFSTOK_DATA, CFSTOK_READ,
CFSTOK_BLOCK|CFSTOK_HOLD, rnd_start, rnd_len, &held);
#endif
#endif /* !CFS_FILE_RW_NOLOCK */
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
+ SSI_ASSERT(result == CFSTOK_HELD);
+#endif /* !CFSTOK_INTR */
#ifdef CFS_ZAP_CACHES
result = cfs_revalidate_inode(inode);
if (!result) {
@@ -292,13 +327,27 @@
struct page *result = NULL;
struct inode *inode = area->vm_file->f_dentry->d_inode;
int prio = ics_getpriority();
+#ifdef CFSTOK_INTR
+ int status;
+#endif
/* Up icsprio to avoid deadlock */
if (prio < ICS_MAX_PRIO)
ics_setpriority(prio + 1);
+#ifdef CFSTOK_INTR
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
+ CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, NULL);
+ if (status != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return ERR_PTR(-EINTR);
+ }
+#else
(void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, NULL);
+#endif
result = filemap_nopage(area, address, typep);
@@ -331,13 +380,27 @@
struct inode *inode = area->vm_file->f_dentry->d_inode;
struct page *result = NULL;
int prio = ics_getpriority();
+#ifdef CFSTOK_INTR
+ int status;
+#endif
/* Up icsprio to avoid deadlock */
if (prio < ICS_MAX_PRIO)
ics_setpriority(prio + 1);
+#ifdef CFSTOK_INTR
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
+ CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, NULL);
+ if (status != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return ERR_PTR(-EINTR);
+ }
+#else
(void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, NULL);
+#endif
result = filemap_nopage(area, address, typep);
@@ -410,13 +473,22 @@
dfprintk(VFS, "cfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino);
#ifdef SSI_CFSTOK_SU
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_SU,
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_SU,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#else
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
+ status = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#endif
-
+#ifdef CFSTOK_INTR
+ if (status != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
+ SSI_ASSERT(status == CFSTOK_HELD);
+#endif
status = cfs_wb_all(inode);
if (!status) {
status = file->f_error;
@@ -515,10 +587,10 @@
cfstok_hl_init(&held);
#ifdef SSI_CFSTOK_SU
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_SU,
+ result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_SU,
CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, &held);
#else
- (void)cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
+ result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_BLOCK|CFSTOK_HOLD, NON_RANGE, &held);
#endif
#ifdef SSI_CFS_FULLTOKENS
@@ -527,10 +599,20 @@
rnd_len = count + (*ppos & (PAGE_CACHE_SIZE - 1));
rnd_len = ((rnd_len + (PAGE_CACHE_SIZE - 1)) >> PAGE_CACHE_SHIFT)
<< PAGE_CACHE_SHIFT;
- (void)cfstok_req(inode, CFSTOK_DATA, CFSTOK_EXCL
+ result = cfstok_req(inode, CFSTOK_DATA, CFSTOK_EXCL
CFSTOK_BLOCK|CFSTOK_HOLD, rnd_start, rnd_len, &held);
#endif
#endif /* !CFS_FILE_RW_NOLOCK */
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
+ SSI_ASSERT(result == CFSTOK_HELD);
+#endif
#ifndef CFS_ZAP_CACHES
/* Don't need to revalidate inode at this point because that ended
@@ -592,7 +674,9 @@
cfs_mntinfo_t *mip = itocmi(inode);
int status = 0;
struct cfslockargs la;
+#ifndef CFS_MIRROR_LOCK_WAIT
int new_lock = 0;
+#endif
dprintk("CFS: cfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n",
inode->i_sb->s_dev, inode->i_ino,
@@ -642,7 +726,17 @@
if (status == 0)
status = res;
}
+#ifndef CFS_MIRROR_LOCK_WAIT
new_lock = 1;
+#else
+ /* Get the mirror lock ahead of the base under rebuild protection */
+ /* By being inside the CFS_SB_FSOP_START, rebuild can't proceed
+ * and storing the mirror lock is safe vs rebuilding server.
+ */
+ if (!status && posix_lock_file_wait(filp, fl) < 0)
+ printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
+ __FUNCTION__);
+#endif
} else if (IS_GETLK(cmd)) {
struct cfsgetlockres res;
@@ -674,16 +768,12 @@
status = -EINVAL;
}
+#ifndef CFS_MIRROR_LOCK_WAIT
/* Get the mirror lock ahead of the base under rebuild protection */
/* By being inside the CFS_SB_FSOP_START, rebuild can't proceed
* and storing the mirror lock is safe vs rebuilding server.
*/
-#ifdef CFS_MIRROR_LOCK_WAIT
- if (new_lock && !status)
- posix_lock_file_wait(filp, fl);
-#else
-#error mirror locks need to be serialized
- /* SSI_XXX: FIXME: use sequence numbers. */
+#warn mirror locks could get out of sync with lock manager
if (new_lock) {
if (!status) {
int err;
Index: dir.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/dir.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- dir.c 10 Oct 2008 08:10:31 -0000 1.23
+++ dir.c 3 Feb 2009 06:18:12 -0000 1.24
@@ -351,6 +351,11 @@
desc->error = CFS_PROTO(inode)->readdir(inode, desc->target,
desc->ptr,
PAGE_CACHE_SIZE);
+#ifdef SSI_CFS_SKIP
+ 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;
@@ -364,7 +369,9 @@
/* Reset read descriptor so it searches the page cache from
* the start upon the next call to readdir_search_pagecache() */
desc->page_index = 0;
- memset(desc->entry, 0, sizeof(*desc->entry));
+ //memset(desc->entry, 0, sizeof(*desc->entry));
+ desc->entry->cookie = desc->entry->prev_cookie = 0;
+ desc->entry->eof = 0;
out:
dfprintk(VFS, "CFS: uncached_readdir() returns %d\n", status);
return status;
@@ -378,7 +385,7 @@
{
struct inode *inode;
int err;
- struct file file;
+ struct file *file;
loff_t origoffset = *offset;
err = cfsd_open(hp, S_IFDIR, MAY_READ, &file);
@@ -388,10 +395,10 @@
goto out_close;
err = -ENOTDIR;
- if (!file.f_op->readdir)
+ if (!file->f_op->readdir)
goto out_close;
if (*offset != 0) {
- err = (int)vfs_llseek(&file, *offset, 0);
+ err = (int)vfs_llseek(file, *offset, 0);
if (err < 0)
goto out_close;
}
@@ -401,7 +408,7 @@
* readdir() is not guaranteed to fill up the entire buffer, but
* may choose to do less.
*/
- inode = file.f_dentry->d_inode;
+ inode = file->f_dentry->d_inode;
down(&inode->i_sem);
err = -ENOENT;
#ifdef SVRCFSTOK_SCT_FLAGS_NOLOCK
@@ -415,12 +422,12 @@
file.f_inode->i_sb->s_dev, file.f_inode->i_ino,
(int) file.f_pos);
*/
- err = file.f_op->readdir(&file, dirent, filldir);
+ err = file->f_op->readdir(file, dirent, filldir);
if (err < 0)
goto out_cfserr;
up(&inode->i_sem);
- *offset = file.f_pos;
+ *offset = file->f_pos;
#if NBITPOFF == 64
dprintk("cfsd: readdir result %Ld bytes, offset %Ld\n",
@@ -431,7 +438,7 @@
#endif
err = 0;
out_close:
- cfsd_close(&file);
+ cfsd_close(file);
out:
return err;
@@ -456,7 +463,16 @@
result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
#ifdef CFS_ZAP_CACHES
res = cfs_revalidate_inode(inode);
@@ -490,12 +506,14 @@
desc->file = filp;
desc->target = filp->f_pos;
- desc->entry = &my_entry;
desc->decode = CFS_PROTO(inode)->decode_dirent;
#ifdef CFS_READDIRPLUS
#warning CFS readdirplus not yet supported.
desc->plus = CFS_USE_READDIRPLUS(inode);
#endif
+ my_entry.cookie = my_entry.prev_cookie = 0;
+ my_entry.eof = 0;
+ desc->entry = &my_entry;
while(!desc->entry->eof) {
res = readdir_search_pagecache(desc);
@@ -639,7 +657,7 @@
dentry->d_time = jiffies;
}
-#if defined(CFS_ZAP_CACHES) && defined(CFS_FILE_RW_NOLOCK)
+#if defined(CFS_ZAP_CACHES) //&& defined(CFS_FILE_RW_NOLOCK)
static inline
int cfs_lookup_verify_inode(struct inode *inode, int isopen)
{
@@ -684,7 +702,7 @@
#endif
parent = dget_parent(dentry);
-#ifdef SSI_EXNFS_XXX
+#ifdef SSI_CFS_SKIP
lock_kernel();
#endif
dir = parent->d_inode;
@@ -721,22 +739,32 @@
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+ dput(parent);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return 0;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
lock = TRUE;
#endif
/* Revalidate parent directory attribute cache */
- cfs_revalidate_inode(dir);
+ (void) cfs_revalidate_inode(dir);
/* Force a full look up iff the parent directory has changed */
if (cfs_check_verifier(dir, dentry)) {
-#ifdef CFS_FILE_RW_NOLOCK
+//#ifdef CFS_FILE_RW_NOLOCK
int isopen = (nd && !(nd->flags & LOOKUP_CONTINUE)
&& (nd->flags & LOOKUP_OPEN));
if (cfs_lookup_verify_inode(inode, isopen))
goto out_zap_parent;
-#endif
+//#endif
goto out_valid;
}
#ifdef CFS_FILE_RW_NOLOCK
@@ -803,16 +831,16 @@
out_valid:
if (lock)
cfstok_relse(dir, CFSTOK_ATTR, CFSTOK_READ, NON_RANGE);
-#ifdef SSI_EXNFS_XXX
+#ifdef SSI_CFS_SKIP
unlock_kernel();
#endif
dput(parent);
return 1;
#ifdef CFS_ZAP_CACHES
-#ifdef CFS_FILE_RW_NOLOCK
+//#ifdef CFS_FILE_RW_NOLOCK
out_zap_parent:
cfs_zap_caches(dir);
-#endif
+//#endif
out_bad:
CFS_CACHEINV(dir, lock);
#else
@@ -830,7 +858,7 @@
d_drop(dentry);
if (lock)
cfstok_relse(dir, CFSTOK_ATTR, CFSTOK_READ, NON_RANGE);
-#ifdef SSI_EXNFS_XXX
+#ifdef SSI_CFS_SKIP
unlock_kernel();
#endif
dput(parent);
@@ -917,7 +945,17 @@
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+ res = ERR_PTR(-EINTR);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ goto out;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
if ((error = _cfs_permission(dir, MAY_EXEC))) {
res = ERR_PTR(error);
@@ -925,7 +963,7 @@
}
#ifdef CFS_ZAP_CACHES
/* Revalidate parent directory attribute cache */
- cfs_revalidate_inode(dir);
+ (void) cfs_revalidate_inode(dir);
#endif
#ifdef SSI_EXNFS_XXX
@@ -985,7 +1023,16 @@
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#endif
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
/* Re-check directory permission with token held */
if ((error = _cfs_permission(dir, MAY_WRITE|MAY_EXEC)))
@@ -1036,7 +1083,16 @@
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#endif
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
/* Re-check directory permission with token held */
if ((error = _cfs_permission(dir, MAY_WRITE|MAY_EXEC)))
@@ -1085,7 +1141,16 @@
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#endif
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
/* Re-check directory permission with token held */
if ((error = _cfs_permission(dir, MAY_WRITE|MAY_EXEC)))
@@ -1159,6 +1224,11 @@
*/
cfs_begin_data_update(dir);
error = CFS_PROTO(dir)->rmdir(dir, &dentry->d_name, ip);
+#ifdef SSI_CFS_SKIP
+ /* Ensure the VFS deletes this inode */
+ if (error == 0 && dentry->d_inode != NULL)
+ dentry->d_inode->i_nlink = 0;
+#endif
cfs_end_data_update(dir);
fail_tokrelse:
@@ -1214,6 +1284,11 @@
cfs_begin_data_update(dir);
cfs_begin_data_update(inode);
error = CFS_PROTO(dir)->remove(dir, &dentry->d_name, inode);
+#ifdef SSI_CFS_SKIP
+ /* The VFS may want to delete this inode */
+ if (error == 0)
+ inode->i_nlink--;
+#endif
cfs_end_data_update(inode);
cfs_end_data_update(dir);
if (!error)
@@ -1222,11 +1297,13 @@
fail_tokrelse:
cfstok_relse_list(&held);
+#ifdef SSI_CFS_SKIP
/* Flush Async writes */
/* SSI_XXX: Do cfs_onlyme() check here, to avoid writes? */
if (!error)
/* Still need? done in ->delete_inode */
(void)cfs_wb_all(inode);
+#endif
fail:
return error;
@@ -1248,7 +1325,7 @@
/* Leave room for a termination byte */
/* SSI_XXX: Really needs to be as large as largest physical fs's */
if (strlen(symname) > maxlen - 1)
- goto out;
+ return error;
#ifdef SSI_CFSTOK_SU
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_SU,
@@ -1257,7 +1334,16 @@
result = cfstok_req(dir, CFSTOK_ATTR, CFSTOK_EXCL,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
#endif
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
/* Re-check directory permission with token held */
if ((error = _cfs_permission(dir, MAY_WRITE|MAY_EXEC)))
@@ -1283,7 +1369,6 @@
#else
cfstok_relse(dir, CFSTOK_ATTR, CFSTOK_EXCL, NON_RANGE);
#endif
-out:
return error;
}
@@ -1600,7 +1685,16 @@
*/
result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, NON_RANGE, NULL);
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
//(void)cfs_revalidate_inode(inode, 1);
error = _cfs_permission(inode, mask);
Index: cfstok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfstok.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- cfstok.c 10 Oct 2008 08:10:31 -0000 1.19
+++ cfstok.c 3 Feb 2009 06:18:12 -0000 1.20
@@ -110,11 +110,15 @@
STATIC void cfstok_queryfunc(object_t *objp, int oldmode, int newmode,
range_off_t start, range_off_t len);
#endif
-STATIC struct ctokhold *checklist( object_t *objp, struct ctokhold **hlist,
+STATIC struct ctokhold *checklist( object_t *objp, hold_list_t *hlist,
struct cfstok *cfstokinfo);
-STATIC struct ctokhold *instholdlist( struct ctokhold **hlist,
+STATIC struct ctokhold *instholdlist( hold_list_t *hlist,
struct cfstok *cfstokinfo, struct ctokhold *entry, int where);
+#ifdef CFSTOKHOLD_LINUX_LIST
+STATIC void delholdlist(struct ctokhold *entry);
+#else
STATIC void delholdlist(struct ctokhold **hlist, struct ctokhold *entry);
+#endif
extern tokseq_t *cfs_tsp;
@@ -223,7 +227,7 @@
struct inode *ip)
{
int which;
- struct ctokhold **list;
+ hold_list_t *list;
object_t obj;
obj.word1 = (long)ip;
@@ -237,7 +241,11 @@
* Initialize HOLD list
*/
list = ITOHDLIST(ip, which);
+#ifdef CFSTOKHOLD_LINUX_LIST
+ INIT_LIST_HEAD(list);
+#else
*list = (struct ctokhold *)NULL;
+#endif
obj.word2 = which;
#ifdef SSI_RANGE_TOKENS
@@ -253,7 +261,7 @@
cfstok_destroy(struct inode *ip)
{
int which;
- struct ctokhold **list;
+ hold_list_t *list;
object_t obj;
obj.word1 = (long)ip;
@@ -264,7 +272,11 @@
for (which = 1; which < CFSTOK_NTOKS + 1; which++) {
list = ITOHDLIST( ip, which);
+#ifdef CFSTOKHOLD_LINUX_LIST
+ SSI_ASSERT(list_empty(list));
+#else
SSI_ASSERT(*list == NULL);
+#endif
obj.word2 = (long)which;
@@ -277,6 +289,7 @@
}
}
+#ifdef SSI_NOTUSED
//enum cfstok_res
cfstok_res_t
cfstok_req_set(
@@ -315,6 +328,7 @@
}
return CFSTOK_HELD;
}
+#endif /* SSI_NOTUSED */
/*
* cfstok_req: hold tokens
@@ -344,9 +358,9 @@
int flags,
range_off_t start,
range_off_t len,
- struct ctokhold **phlist) /* addr of ptr to proc's holdlist */
+ hold_list_t *phlist) /* addr of ptr to proc's holdlist */
{
- struct ctokhold **hlist;/* addr of ptr to holdlist on cnode */
+ hold_list_t *hlist;/* addr of ptr to holdlist on cnode */
struct ctokhold *entry=(struct ctokhold *)NULL;
struct cfstok ctok;
object_t obj;
@@ -374,8 +388,6 @@
len = MAXLEN;
}
- CFSTOK_XLOCK( itoc(ip));/* exclusive lock token info in cfs inode*/
-
/*
* Check for illegal combinations
*/
@@ -398,6 +410,8 @@
obj.word2 = (long)which_tok;
obj.obj_pp = &cliparam;
+ CFSTOK_XLOCK( itoc(ip));/* exclusive lock token info in cfs inode*/
+
if (flags & CFSTOK_HOLD) {
if ((entry = (struct ctokhold *)checklist(&obj, hlist, &ctok))) {
@@ -411,8 +425,8 @@
* Add the new entry to begining of caller's
* hold list.
*/
- if( phlist != (struct ctokhold **)NULL)
- instholdlist( phlist, &ctok, NULL, INS_START);
+ if (phlist)
+ (void) instholdlist( phlist, &ctok, NULL, INS_START);
ret = CFSTOK_HELD;
goto unlock;
}
@@ -451,12 +465,12 @@
/*
* Add to the front of caller's holdlist
*/
- if( phlist != (struct ctokhold **)NULL)
- instholdlist( phlist, &ctok, NULL, INS_START);
+ if (phlist)
+ (void) instholdlist( phlist, &ctok, NULL, INS_START);
/*
* Add to the end of inode hold list
*/
- instholdlist(hlist, &ctok, NULL, INS_END);
+ (void) instholdlist(hlist, &ctok, NULL, INS_END);
ret = CFSTOK_HELD;
} else {
ret = CFSTOK_WOULDBLOCK;
@@ -489,7 +503,11 @@
* indicate that this process has the
* token.
*/
- instholdlist( hlist, &ctok, NULL, INS_END);
+#ifdef CFSTOK_INTR
+ entry = instholdlist( hlist, &ctok, NULL, INS_END);
+#else
+ (void) instholdlist( hlist, &ctok, NULL, INS_END);
+#endif
CFSTOK_XRELE(itoc(ip));
#ifdef SSI_NOTYET
if (flags & CFSTOK_CXUNLOCK)
@@ -504,21 +522,32 @@
tok_wait_range(waitcookie);
else
#endif
+#ifdef CFSTOK_INTR
+ if (tok_wait(waitcookie)) {
+ /* Interrupted */
+ CFSTOK_XLOCK( itoc(ip));
+ BUG_ON(list_empty(&entry->ctok_list));
+ delholdlist(entry);
+ ret = CFSTOK_WOULDBLOCK;
+ goto unlock;
+ }
+#else
tok_wait( ITOTCB(ip, which_tok),
waitcookie );
+#endif /* !CFSTOK_INTR */
#ifdef SSI_NOTYET
if (flags & CFSTOK_CXUNLOCK)
CXLOCK(cp);
#endif
ret = CFSTOK_HELD;
if (phlist)
- instholdlist( phlist, &ctok, NULL, INS_START);
+ (void) instholdlist( phlist, &ctok, NULL, INS_START);
goto no_unlock;
} else {
ret = CFSTOK_HELD;
- instholdlist( hlist, &ctok, NULL, INS_END);
+ (void) instholdlist( hlist, &ctok, NULL, INS_END);
if (phlist)
- instholdlist( phlist, &ctok, NULL, INS_START);
+ (void) instholdlist( phlist, &ctok, NULL, INS_START);
goto unlock;
}
@@ -545,8 +574,10 @@
*/
int
-cfstok_req_m(int num_lock, cfs_lockop_t * ops,
- struct ctokhold **phlist)
+cfstok_req_m(
+ int num_lock,
+ cfs_lockop_t * ops,
+ hold_list_t *phlist)
{
cfs_lockop_t *point[num_lock], *tmp;
int x;
@@ -598,11 +629,25 @@
status = cfstok_req(point[x]->lo_ip, point[x]->lo_which,
point[x]->lo_mode, CFSTOK_HOLD|CFSTOK_BLOCK,
NON_RANGE, phlist);
+#ifdef CFSTOK_INTR
+ if (status != CFSTOK_HELD)
+ break;
+#else
SSI_ASSERT(status == CFSTOK_HELD);
+#endif
}
-#ifdef SSI_XXX_CFS_NEED_ERROR_HANDLING
/* On error unlock the locks that we did hold */
+#ifdef CFSTOK_INTR
+ if (x < num_lock) {
+ cfstok_relse_list(phlist);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return -EINTR;
+ }
+#else
+#ifdef SSI_XXX_CFS_NEED_ERROR_HANDLING
/* SSI_XXX: To really make this work need to release phlist stuff */
if (x < num_lock) {
int y;
@@ -611,6 +656,7 @@
point[y]->mode, NON_RANGE);
}
#endif
+#endif /* !CFSTOK_INTR */
return error;
}
@@ -645,14 +691,12 @@
int flags,
int delay)
{
- struct ctokhold **hlist;
+ hold_list_t *hlist;
struct ctokhold *retlist=(struct ctokhold *)NULL;
struct cfstok tokinfo;
object_t obj;
int ret;
- CFSTOK_XLOCK( itoc(ip));/* exclusive lock token info in cfs inode*/
-
hlist = ITOHDLIST( ip, which);
tokinfo.which = which;
@@ -668,6 +712,8 @@
obj.word2 = (long)which;
obj.obj_pp = &cliparam;
+ CFSTOK_XLOCK( itoc(ip));/* exclusive lock token info in cfs inode*/
+
if ((retlist = (struct ctokhold *)checklist(&obj, hlist, &tokinfo)) !=NULL){
if ( retlist->ctok.held_count > 1 ){
@@ -709,7 +755,11 @@
/*
* delete from inode's hold list
*/
+#ifdef CFSTOKHOLD_LINUX_LIST
+ delholdlist(retlist);
+#else
delholdlist( hlist, retlist);
+#endif
CFSTOK_XRELE(itoc(ip));
process_msgs(FALSE);
@@ -720,27 +770,25 @@
panic( "cfstok_relsex: No hold found");
}
-void
-cfstok_relse_list(
- struct ctokhold **usrlist)
-{
- cfstok_relse_listx(usrlist, 0, 0);
-}
-
-void
+static inline void
cfstok_relse_listx(
- struct ctokhold **usrlist,
+ hold_list_t *usrlist,
int flags,
int delay)
{
struct ctokhold *rellist;
+#ifdef CFSTOKHOLD_LINUX_LIST
+ struct ctokhold *tmp;
+ list_for_each_entry_safe(rellist, tmp, usrlist, ctok_list) {
+#else
if ((*usrlist) == NULL)
return;
while(*usrlist) {
rellist = *usrlist;
+#endif /* !CFSTOKHOLD_LINUX_LIST */
cfstok_relsex( rellist->ctok.ip, rellist->ctok.which,
rellist->ctok.mode, rellist->ctok.start,
LEN(rellist->ctok), flags, delay );
@@ -748,10 +796,19 @@
/*
* delete this list element from user list
*/
-
+#ifdef CFSTOKHOLD_LINUX_LIST
+ delholdlist(rellist);
+#else
delholdlist( usrlist, rellist);
+#endif
}
+}
+void
+cfstok_relse_list(
+ hold_list_t *usrlist)
+{
+ cfstok_relse_listx(usrlist, 0, 0);
}
void
@@ -773,7 +830,7 @@
{
int check;
- struct ctokhold **hlist;
+ hold_list_t *hlist;
struct ctokhold *lastlist;
struct ctokhold *walklist;
struct ctokhold *tlist;
@@ -783,6 +840,15 @@
*/
for( check = ctok->which + 1; check < CFSTOK_NTOKS; check++){
hlist = ITOHDLIST( ip, ctok->which);
+#ifdef CFSTOKHOLD_LINUX_LIST
+ /*
+ * check for matching pids i.e other
+ * process may hold
+ */
+ list_for_each_entry(walklist, hlist, ctok_list)
+ if ( walklist->ctok.unique == NSC_UNIQUE_ID )
+ return CFSTOK_EOUTORDER;
+#else
if ( *hlist != NULL) {
/*
* check for matching pids i.e other
@@ -795,6 +861,7 @@
walklist = walklist->next;
}
}
+#endif /* !CFSTOKHOLD_LINUX_LIST */
}
/*
@@ -813,7 +880,11 @@
hlist = ITOHDLIST(ip, ctok->which);
lastlist = NULL;
+#ifdef CFSTOKHOLD_LINUX_LIST
+ list_for_each_entry(tlist, hlist, ctok_list)
+#else
for (tlist = *hlist ; tlist != NULL ; tlist = tlist->next)
+#endif
if (tlist->ctok.unique == NSC_UNIQUE_ID )
lastlist = tlist;
@@ -836,12 +907,16 @@
STATIC struct ctokhold *
checklist(
object_t *objp,
- struct ctokhold **hlist, /* where to search */
+ hold_list_t *hlist, /* where to search */
struct cfstok *cfstokinfo) /* search from this information */
{
register struct ctokhold *foundptr;
+#ifdef CFSTOKHOLD_LINUX_LIST
+ list_for_each_entry(foundptr, hlist, ctok_list) {
+#else
for (foundptr = *hlist; foundptr !=NULL ; foundptr = foundptr->next) {
+#endif
SSI_ASSERT(foundptr->ctok.which == cfstokinfo->which);
@@ -865,9 +940,22 @@
return (struct ctokhold *)NULL;
}
+#ifdef CFSTOK_KMEM_CACHE
+STATIC kmem_cache_t *ctokhold_cachep;
+
+void
+cfstokhold_init(void)
+{
+ ctokhold_cachep = kmem_cache_create("cfstok_cache",
+ sizeof(struct ctokhold), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#else
STATIC struct ctokhold *ctokhold_free = NULL;
STATIC int ctokhold_free_count = 0;
SPIN_LOCK_T ctokhold_free_lock;
+#endif
/*
@@ -883,15 +971,21 @@
STATIC struct ctokhold *
instholdlist(
- struct ctokhold **hlist,
+ hold_list_t *hlist,
struct cfstok *cfstokinfo,
struct ctokhold *entry,
int where)
{
register struct ctokhold *inst;
+#ifndef CFSTOKHOLD_LINUX_LIST
register struct ctokhold *endlist=(struct ctokhold *)NULL;
register struct ctokhold *tmplist=(struct ctokhold *)NULL;
+#endif
+#ifdef CFSTOK_KMEM_CACHE
+ inst = kmem_cache_alloc(ctokhold_cachep, GFP_KERNEL|__GFP_NOFAIL);
+ memset(inst, 0, sizeof(struct ctokhold));
+#else
LOCK_SPIN_LOCK(&ctokhold_free_lock);
if ((inst = ctokhold_free)) {
ctokhold_free = inst->next;
@@ -909,7 +1003,24 @@
}
memset(inst, 0, sizeof(struct ctokhold));
}
+#endif /* !CFSTOK_KMEM_CACHE */
+
+#ifdef CFSTOKHOLD_LINUX_LIST
+ INIT_LIST_HEAD(&inst->ctok_list);
+ inst->ctok = *((cfstok_t *)cfstokinfo);
+ switch (where) {
+ case INS_START:
+ list_add(&inst->ctok_list, hlist);
+ break;
+ case INS_END:
+ list_add_tail(&inst->ctok_list, hlist);
+ break;
+ default:
+ list_add(&inst->ctok_list, &entry->ctok_list);
+ break;
+ }
+#else
inst->next = (struct ctokhold *)NULL;
inst->prev = (struct ctokhold *)NULL;
@@ -940,6 +1051,7 @@
entry->next = inst;
inst->prev = entry;
}
+#endif /* !CFSTOKHOLD_LINUX_LIST */
return (struct ctokhold *)inst;
}
@@ -951,23 +1063,36 @@
*/
STATIC void
+#ifdef CFSTOKHOLD_LINUX_LIST
delholdlist(
- struct ctokhold **hlist,
struct ctokhold *entry)
+#else
+delholdlist(
+ hold_list_t *hlist,
+ struct ctokhold *entry)
+#endif
{
+#ifdef CFSTOKHOLD_LINUX_LIST
+ list_del_init(&entry->ctok_list);
+#else
if ( entry->prev != NULL)
entry->prev->next = entry->next;
else
*hlist = entry->next;
if ( entry->next != NULL)
entry->next->prev = entry->prev;
+#endif
+#ifdef CFSTOK_KMEM_CACHE
+ kmem_cache_free(ctokhold_cachep, entry);
+#else
/* Free entry */
LOCK_SPIN_LOCK(&ctokhold_free_lock);
entry->next = ctokhold_free;
ctokhold_free = entry;
ctokhold_free_count++;
UNLOCK_SPIN_LOCK(&ctokhold_free_lock);
+#endif
}
/*
@@ -1209,7 +1334,7 @@
cfstok_giveback(
struct inode *ip)
{
- struct ctokhold **list;
+ hold_list_t *list;
agent_t agent;
int which;
int ret;
@@ -1264,7 +1389,11 @@
for (which = CFSTOK_NTOKS; which > 0 ; which--) {
list = ITOHDLIST(ip, which);
+#ifdef CFSTOKHOLD_LINUX_LIST
+ SSI_ASSERT(list_empty(list));
+#else
SSI_ASSERT(*list == NULL);
+#endif
agent = this_node;
obj.word1 = (long)ip;
@@ -1587,9 +1716,6 @@
break;
#endif
case CFSTOK_SR:
-#ifdef CFS_ZAP_CACHES
- /* refresh will determine whether need revalidation */
-#else
/* SSI_XXX: It would be better if we could downgrade these
* mappings to read-only until he does a write fault.
* This is not possible in Linux without further modifications.
@@ -1600,13 +1726,9 @@
#else
unmap_mapping_range(ip->i_mapping, 0, 0, 0);
#endif /* !SSI_RANGE_TOKENS */
-#endif /* !CFS_ZAP_CACHES */
break;
case TOK_NOMODE:
case CFSTOK_NULL:
-#ifdef CFS_ZAP_CACHES
- /* refresh will determine whether need revalidation */
-#else
#ifdef SSI_RANGE_TOKENS
if (!len || (!start && len == MAXLEN))
goto nonrange;
@@ -1632,6 +1754,11 @@
#endif
nonrange:
#endif /* SSI_RANGE_TOKENS */
+#ifdef CFS_ZAP_CACHES
+ LOCK_COND_LOCK(&itoc(ip)->c_statelock);
+ CFS_FLAGS(ip) |= CFS_INO_INVALID_ATTR | CFS_INO_INVALID_DATA;
+ UNLOCK_COND_LOCK(&itoc(ip)->c_statelock);
+#else
unmap_mapping_range(ip->i_mapping, 0, 0, 0);
filemap_write_and_wait(ip->i_mapping);
invalidate_inode_pages2(ip->i_mapping);
@@ -1866,19 +1993,28 @@
struct inode *ip,
svrhold_list_t *hlistp)
{
+ object_t obj;
+#ifdef SVRHOLD_LIST_LINUX_LIST
+ hlist_t *item, *tmp;
+#else
hlist_t *item;
- int i;
u_int count;
- object_t obj;
+ int i;
count = hlist_count(hlistp);
+#endif
CFSTOK_XLOCK( itoc(ip));/* exclusive lock token info in cfs inode*/
+#ifdef SVRHOLD_LIST_LINUX_LIST
+ list_for_each_entry_safe(item, tmp, hlistp, hl_list) {
+ list_del(&item->hl_list);
+#else
for (i = 0 ; i < count ; i++) {
item = hlist_extract(hlistp);
if (item == NULL)
panic("cfstok_install_list: Internal Error\n");
+#endif
SSI_ASSERT(item->hl_op == INSTALL);
SSI_ASSERT(item->hl_type != CFSTOK_MHOLD);
@@ -1948,10 +2084,23 @@
process_msgs(FALSE);
}
+#ifdef CFSTOK_KMEM_CACHE
+STATIC kmem_cache_t *delrel_cachep;
+
+void
+cfs_delrel_init(void)
+{
+ delrel_cachep = kmem_cache_create("cfsdr_cache",
+ sizeof(struct delrel), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#else
/* Delay Release Structure free list */
STATIC struct delrel *dr_free = NULL;
STATIC int dr_free_count = 0;
SPIN_LOCK_T dr_free_lock;
+#endif
/* List of Delay Releases needed to be processed by the CFS daemon */
STATIC struct delrel *delrel_list = NULL;
@@ -1990,6 +2139,7 @@
while(delrel_list) {
/* Pull one from list */
drp = delrel_list;
+ mb();
delrel_list = drp->dr_next;
UNLOCK_SOFTIRQ_SPIN_LOCK(&dr_list_lock);
@@ -1999,12 +2149,16 @@
drp->dr_mode, drp->dr_start, drp->dr_len);
iput(drp->dr_ip);
+#ifdef CFSTOK_KMEM_CACHE
+ kmem_cache_free(delrel_cachep, drp);
+#else
/* Now can be put on free list */
LOCK_SPIN_LOCK(&dr_free_lock);
drp->dr_next = dr_free;
dr_free = drp;
dr_free_count++;
UNLOCK_SPIN_LOCK(&dr_free_lock);
+#endif
LOCK_SOFTIRQ_SPIN_LOCK(&dr_list_lock);
}
@@ -2026,6 +2180,7 @@
/* Put release on Daemons list */
LOCK_SOFTIRQ_SPIN_LOCK(&dr_list_lock);
drp->dr_next = delrel_list;
+ mb();
delrel_list = drp;
UNLOCK_SOFTIRQ_SPIN_LOCK(&dr_list_lock);
@@ -2078,6 +2233,10 @@
{
struct delrel *drp;
+#ifdef CFSTOK_KMEM_CACHE
+ drp = kmem_cache_alloc(delrel_cachep, GFP_KERNEL|__GFP_NOFAIL);
+ memset(drp, 0, sizeof(struct delrel));
+#else
/* Get struct from free list if possible */
LOCK_SPIN_LOCK(&dr_free_lock);
if ((drp = dr_free)) {
@@ -2091,6 +2250,7 @@
panic("cfs_delrel_add: Out of memory");
memset(drp, 0, sizeof(struct delrel));
}
+#endif /* !CFSTOK_KMEM_CACHE */
/* Hold inode because we are referencing it here */
atomic_inc(&ip->i_count);
@@ -2446,6 +2606,7 @@
return waiters;
} /* cfstok_waitcount() */
+#ifndef CFSTOK_KMEM_CACHE
int
cfstok_free_memory(int count, unsigned int gfp_mask)
{
@@ -2516,3 +2677,4 @@
}
return dr_free_count;
}
+#endif /* !CFSTOK_KMEM_CACHE */
Index: cfsproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfsproc.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- cfsproc.c 10 Oct 2008 08:10:31 -0000 1.28
+++ cfsproc.c 3 Feb 2009 06:18:12 -0000 1.29
@@ -121,8 +121,7 @@
filp->f_op = fops_get(inode->i_fop);
atomic_set(&filp->f_count, 1);
- dget(dentry);
- filp->f_dentry = dentry;
+ filp->f_dentry = dget(dentry);
filp->f_vfsmnt = NULL; /* SSI_XXX: Do I need something? */
filp->f_flags = O_RDONLY|O_LARGEFILE;
@@ -172,7 +171,9 @@
struct svrcfstok *hp;
svrhold_list_t new_hold_list;
__u32 *fh = (__u32 *)&(argp->cgia_fh);
+#ifndef CFS_FH_TO_DENTRY_ANON
struct super_block *sb = NULL;
+#endif
dprintk("nfsd: GETINODE %s\n", SVCFH_fmt(&argp->cgia_fh));
@@ -242,6 +243,7 @@
cfserr = -ESTALE;
goto out;
}
+ /* SSI_XXX: Missing dput ? */
#endif /* ! CFS_FH_TO_DENTRY_ANON */
}
@@ -265,8 +267,10 @@
resp->cdr_status = cfserr;
if (hp)
HASH_RELE(hp);
+#ifndef CFS_FH_TO_DENTRY_ANON
if (sb)
drop_super(sb);
+#endif
}
#ifdef CFS_REVALIDATE_GETATTR
@@ -439,6 +443,17 @@
*/
int
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_READ
+rcfs_read(
+ clusternode_t node,
+ int *rval,
+ struct cfsreadargs *argp,
+ struct cfsrdresults **respp,
+ struct kvec **vec,
+ int *vlen,
+ char **buffpp,
+ int *buffer_len)
+#else
rcfs_read(
clusternode_t node,
int *rval,
@@ -447,6 +462,7 @@
unsigned long *count,
struct kvec **vec,
int *vlen)
+#endif
#else
rcfs_read(
clusternode_t node,
@@ -455,17 +471,20 @@
struct cfsrdresults **respp,
char **buffpp,
int *buffer_len)
-#endif
+#endif /* !CFS_PAGEVEC */
{
int cfserr;
struct svrcfstok *hp;
struct cfsrdresults *resp;
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_READ)
unsigned long mycount = *count;
struct kvec *__vec;
int i;
+#ifdef CFS_PAGEVEC_PAGE_ORDER
+ unsigned int order;
+#endif
#define LAST_VEC_LEN(x) \
- (((x - 1) & ~PAGE_CACHE_MASK) + 1)
+ (((x - 1) & ~PAGE_MASK) + 1)
#else
unsigned long mycount = *buffer_len;
char *buffer;
@@ -480,7 +499,7 @@
BUG();
#endif
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_READ)
#ifdef CFS_PARANOIA
SSI_ASSERT(*vlen <= CFS_READ_MAXIOV);
#endif
@@ -488,14 +507,39 @@
*vec = __vec = kmalloc_nofail(*vlen * sizeof(struct kvec));
/* Setup kvec array */
+#ifdef CFS_PAGEVEC_PAGE_ORDER
+ for (order = 0; (PAGE_SIZE << order) < *count; order++)
+ ;
+ /* SSI_XXX: Borrowing mycount to track unused pages */
+ mycount = __vec->iov_base =
+ (void *) __get_free_pages(GFP_KERNEL|__GFP_NOFAIL, order);
+ __vec->iov_len = PAGE_SIZE - argp->cra_pgbase;
+ __vec++;
+
+ for (i = 1; i < *vlen; __vec++, i++) {
+ mycount += PAGE_SIZE;
+ __vec->iov_base = mycount;
+ __vec->iov_len = PAGE_SIZE;
+ }
+ (__vec-1)->iov_len = LAST_VEC_LEN(*count + argp->cra_pgbase);
+
+ /* Dealloc unused pages */
+ for (mycount += PAGE_SIZE;
+ mycount < (PAGE_SIZE << order);
+ mycount += PAGE_SIZE) {
+ free_page(mycount);
+ }
+ mycount = *count;
+#else
__vec->iov_base = (void *) __get_free_page(GFP_KERNEL|__GFP_NOFAIL);
- __vec->iov_len = PAGE_CACHE_SIZE - argp->cra_pgbase;
+ __vec->iov_len = PAGE_SIZE - argp->cra_pgbase;
__vec++;
for (i = 1; i < *vlen; __vec++, i++) {
__vec->iov_base = (void *) __get_free_page(GFP_KERNEL|__GFP_NOFAIL);
- __vec->iov_len = PAGE_CACHE_SIZE;
+ __vec->iov_len = PAGE_SIZE;
}
(__vec-1)->iov_len = LAST_VEC_LEN(mycount + argp->cra_pgbase);
+#endif /* !CFS_PAGEVEC_PAGE_ORDER */
hp = fhtohp(&(argp->cra_fhandle));
@@ -512,8 +556,8 @@
int __vlen = *vlen;
int mycount_base = mycount + argp->cra_pgbase;
- *vlen = (mycount) ? PAGE_CACHE_ALIGN(mycount_base)
- >> PAGE_CACHE_SHIFT : 0;
+ *vlen = (mycount) ? PAGE_ALIGN(mycount_base)
+ >> PAGE_SHIFT : 0;
__vec = (struct kvec *)(*vec + *vlen);
if (*vlen)
(__vec-1)->iov_len = LAST_VEC_LEN(mycount_base);
@@ -533,7 +577,12 @@
*buffpp = buffer = kmalloc_nofail(mycount); //kzmalloc_nofail(mycount);
hp = fhtohp(&(argp->cra_fhandle));
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ *vec = NULL, *vlen = 0;
+ cfserr = cfsd_read(hp, argp->cra_offset, *vec, *vlen, buffer, &mycount);
+#else
cfserr = cfsd_read(hp, argp->cra_offset, buffer, &mycount);
+#endif
*respp = resp = kmalloc_nofail(sizeof(*resp));
@@ -542,7 +591,7 @@
/* For simple disk filesystem (ext2) this doesn't fail */
cfserr = cfsd_getattr(hp, &(resp->crr_attr));
}
-#endif /* ! CFS_PAGEVEC */
+#endif /* !( CFS_PAGEVEC && !CFS_PAGEVEC_BUFFER_READ ) */
HASH_RELE(hp);
resp->crr_status = cfserr;
*rval = 0;
@@ -567,6 +616,17 @@
*/
int
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+rcfs_write(
+ clusternode_t node,
+ int *rval,
+ struct cfswriteargs *argp,
+ struct cfswriteres **resp_p,
+ struct kvec **kvec,
+ int vlen,
+ char *buffer,
+ int buffer_len)
+#else
rcfs_write(
clusternode_t node,
int *rval,
@@ -575,6 +635,7 @@
unsigned long count,
struct kvec **kvec,
int vlen)
+#endif
#else
rcfs_write(
clusternode_t node,
@@ -583,29 +644,41 @@
struct cfswriteres **resp_p,
char *buffer,
int buffer_len)
-#endif
+#endif /* !CFS_PAGEVEC */
{
int cfserr;
struct svrcfstok *hp;
struct cfswriteres *resp;
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ dprintk("cfsd: WRITE %s %u bytes at %Ld vlen=%d\n",
+ SVCFH_fmt(&argp->cwa_fhandle),
+ buffer_len, (long long)argp->cwa_offset, vlen);
+#else
dprintk("cfsd: WRITE %s %lu bytes at %Ld vlen=%d\n",
SVCFH_fmt(&argp->cwa_fhandle),
count, (long long)argp->cwa_offset, vlen);
+#endif
#else
dprintk("cfsd: WRITE %s %d bytes at %Ld\n",
SVCFH_fmt(&argp->cwa_fhandle),
buffer_len, (long long)argp->cwa_offset);
-#endif
+#endif /* !CFS_PAGEVEC */
hp = fhtohp(&(argp->cwa_fhandle));
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ SSI_ASSERT(!vlen);
+ cfserr = cfsd_write(hp, argp->cwa_offset, *kvec, vlen,
+ buffer, (unsigned long) buffer_len, argp->cwa_stable);
+#else
cfserr = cfsd_write(hp, argp->cwa_offset, *kvec, vlen, count,
argp->cwa_stable);
+#endif
#else
cfserr = cfsd_write(hp, argp->cwa_offset, buffer, buffer_len,
argp->cwa_stable);
-#endif
+#endif /* !CFS_PAGEVEC */
*resp_p = resp = kmalloc_nofail(sizeof(cfswriteres));
if (!cfserr) {
@@ -1588,8 +1661,7 @@
*/
if (ip == pfs_sb->s_root->d_inode) {
iput(ip);
- dp = pfs_sb->s_root;
- dget(dp);
+ dp = dget(pfs_sb->s_root);
} else
dp = d_alloc_root(ip);
#ifdef CFS_DECODE_FH
@@ -1615,7 +1687,7 @@
args->chr_ropncnt, args->chr_wopncnt);
#endif
- svrtok_relse(hp);
+ HASH_RELE(hp);
out:
*statusp = error;
return;
@@ -1638,14 +1710,6 @@
dentry = hp->sct_dp;
SSI_ASSERT(dentry);
-#ifndef CFS_MIRROR_LOCK_WAIT
- /* SSI_XXX: Mirror locks need to be ordered.
- * Should embed lock in range token.
- * -Roger
- */
- CXLOCK(itoc(inode));
-#endif
-
error = -ENOLCK;
/* SSI_XXX: Why not just have this on the stack? */
fl = (struct file_lock *) kmalloc(sizeof(*fl), GFP_KERNEL);
@@ -1679,9 +1743,6 @@
out:
kfree(fl);
*statusp = error;
-#ifndef CFS_MIRROR_LOCK_WAIT
- CXUNLOCK(itoc(inode));
-#endif
HASH_RELE(hp);
}
@@ -1851,7 +1912,7 @@
/* SSI_XXX: Not using sa_datasync at this point */
cfsd_sync_dir(hp->sct_dp, args->sa_datasync);
- svrtok_relse(hp);
+ HASH_RELE(hp);
out:
*statusp = error;
return;
Index: symlink.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/symlink.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- symlink.c 10 Oct 2008 08:10:32 -0000 1.10
+++ symlink.c 3 Feb 2009 06:18:12 -0000 1.11
@@ -181,7 +181,16 @@
result = cfstok_req(inode, CFSTOK_ATTR, CFSTOK_READ,
CFSTOK_HOLD|CFSTOK_BLOCK, 0, 0, NULL);
+#ifdef CFSTOK_INTR
+ if (result != CFSTOK_HELD) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Interrupted\n", __FUNCTION__);
+#endif
+ return ERR_PTR(-EINTR);
+ }
+#else
SSI_ASSERT(result == CFSTOK_HELD);
+#endif
/* SSI_XXX: Mark ATIME here */
Index: proc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/proc.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- proc.c 10 Oct 2008 08:10:32 -0000 1.18
+++ proc.c 3 Feb 2009 06:18:12 -0000 1.19
@@ -47,22 +47,75 @@
#include <cluster/assert.h>
#ifdef CFS_PAGEVEC
-#define CFS_PAGEVEC_MAP(_data, _kvec, _vlen) \
- { \
+#if defined(CFS_PAGEVEC_BUFFER_READ) || defined(CFS_PAGEVEC_BUFFER_WRITE)
+#define CFS_PAGEVEC_MAP_BUFFER(_data, _buf, _iswrite) do { \
+ if (_data->page) { \
+ _buf = kmap(_data->page) + _data->pgbase; \
+ break; \
+ } \
+ _buf = kmalloc(_data->count, GFP_NOFS|__GFP_NOFAIL); \
+ if (_iswrite) { \
+ struct list_head *pos; \
+ caddr_t _iov_base, _buffer = _buf; \
+ \
+ list_for_each(pos, &_data->pages) { \
+ struct cfs_page *req = cfs_list_entry(pos); \
+ \
+ _iov_base = kmap(req->wb_page) + req->wb_offset; \
+ memcpy(_buffer, _iov_base, req->wb_bytes); \
+ kunmap(req->wb_page); \
+ _buffer += req->wb_bytes; \
+ } \
+ } \
+} while (0)
+
+#define CFS_PAGEVEC_UNMAP_BUFFER(_data, _buf, _read) do { \
+ if (_data->page) { \
+ kunmap(_data->page); \
+ break; \
+ } else if (_read > 0) { \
struct list_head *pos; \
+ caddr_t _buffer = _buf; \
+ ssize_t _count = _read; \
+ \
+ /* Take care of truncated reads too */ \
+ list_for_each(pos, &_data->pages) { \
+ struct cfs_page *req = cfs_list_entry(pos); \
+ caddr_t _iov_base; \
+ \
+ _iov_base = kmap(req->wb_page) + req->wb_offset; \
+ if (_count < req->wb_bytes) \
+ memcpy(_iov_base, _buffer, _count); \
+ else \
+ memcpy(_iov_base, _buffer, req->wb_bytes); \
+ kunmap(req->wb_page); \
\
+ if (_count <= req->wb_bytes) \
+ break; \
+ _count -= req->wb_bytes; \
+ _buffer += req->wb_bytes; \
+ } \
+ } \
+ kfree(_buf); \
+} while (0)
+#endif /* CFS_PAGEVEC_BUFFER_READ || CFS_PAGEVEC_BUFFER_WRITE */
+
+#define CFS_PAGEVEC_MAP(_data, _kvec, _vlen) \
+ do { \
if (unlikely(_data->page)) { \
_vlen = 1; \
- _kvec = kmalloc_nofail(sizeof(struct kvec)); \
+ _kvec = kmalloc(sizeof(struct kvec), GFP_NOFS|__GFP_NOFAIL); \
\
_kvec->iov_base = kmap(_data->page) + _data->pgbase; \
_kvec->iov_len = _data->count; \
} else { \
+ struct list_head *pos; \
struct kvec *__kvec; \
\
+ _vlen = 0; \
list_for_each(pos, &_data->pages) _vlen++; \
\
- __kvec = _kvec = kmalloc_nofail(sizeof(struct kvec) * _vlen); \
+ __kvec = _kvec = kmalloc(sizeof(struct kvec) * _vlen, GFP_NOFS|__GFP_NOFAIL); \
\
list_for_each(pos, &_data->pages) { \
struct cfs_page *req = cfs_list_entry(pos); \
@@ -72,10 +125,10 @@
__kvec++; \
} \
} \
- }
+ } while (0)
#define CFS_PAGEVEC_UNMAP(_data, _kvec) \
- { \
+ do { \
if (unlikely(_data->page)) { \
kunmap(_data->page); \
} else { \
@@ -86,7 +139,7 @@
} \
} \
kfree(_kvec); \
- }
+ } while (0)
#endif
@@ -111,6 +164,11 @@
if (status)
goto sb_error_check;
+#ifdef CFS_FH_TO_DENTRY_ANON
+ /* Overwrite possible stale ssidev */
+ ((__u32 *)fhandle)[0] = server->mi_sb->s_ssidev;
+#endif
+
if (CFS_AT_SERVER_MIP(server)) {
#ifdef CFS_FH_TO_DENTRY_ANON
struct svrcfstok *hp;
@@ -166,7 +224,7 @@
dentry->d_flags |= DCACHE_DISCONNECTED;
found:
hp = makehp(NULL, server->mi_sb->s_ssidev, dentry);
- dput(dentry); /* BUG: extra dput ? -Roger */
+ dput(dentry);
#endif /* ! CFS_FH_TO_DENTRY_ANON */
*ipp = __cfs_hpget(server->mi_sb, hp, *ipp);
@@ -448,10 +506,13 @@
int status;
#ifdef CFS_PAGEVEC
struct kvec *kvec;
- int vlen = 0;
- char async = (data->flags & RPC_TASK_ASYNC);
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ caddr_t buffer;
+ loff_t offset = data->offset;
+#endif
cfs_mntinfo_t *mip = itocmi(data->inode);
struct inode *inode = data->inode;
+ int vlen, async = (data->flags & RPC_TASK_ASYNC);
#else
cfs_mntinfo_t *mip = itocmi(inode);
#endif
@@ -468,7 +529,7 @@
if (status)
goto sb_error_check;
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_READ)
CFS_PAGEVEC_MAP(data, kvec, vlen);
#endif
@@ -477,7 +538,14 @@
unsigned long mycount = data->count;
/* SSI_XXX: Maximum ssize_t byte chunks */
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ buffer = NULL;
+ CFS_PAGEVEC_MAP(data, kvec, vlen);
+ status = cfsd_read(itoc(inode)->c_hp, data->offset, kvec, vlen, buffer, &mycount);
+ CFS_PAGEVEC_UNMAP(data, kvec);
+#else
status = cfsd_read(itoc(inode)->c_hp, data->offset, kvec, vlen, &mycount);
+#endif
if (status == 0) {
data->res_count = mycount;
#else
@@ -500,13 +568,17 @@
struct cfsrdresults *res_p = NULL;
int rval;
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ int mycount = data->count;
+#else
unsigned long mycount = data->count;
+#endif
#else
int mycount = count;
#endif
args.cra_fhandle = *itocfh(inode);
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_READ)
args.cra_offset = data->offset;
args.cra_pgbase = data->pgbase;
@@ -515,26 +587,44 @@
#else
args.cra_offset = offset;
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ kvec = NULL, vlen = 0;
+ CFS_PAGEVEC_MAP_BUFFER(data, buffer, 0);
+ status = RCFS_READ(mip->mi_server, &rval,
+ &args, &res_p, &kvec, &vlen,
+ (char **)&buffer, &mycount);
+#else
status = RCFS_READ(mip->mi_server,&rval,
&args, &res_p, (char **)&buffer,&mycount);
#endif
+#endif
- if (status != 0 || rval != 0)
+ if (status != 0 || rval != 0) {
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ CFS_PAGEVEC_UNMAP_BUFFER(data, buffer, 0);
+#endif
status = -ETIMEDOUT;
- if (status == 0) {
+ } else if (status == 0) {
status = res_p->crr_status;
if (status == 0) {
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ CFS_PAGEVEC_UNMAP_BUFFER(data, buffer, (ssize_t)mycount);
+#endif
data->res_count = mycount;
#endif
status = (ssize_t)mycount;
cfs_refresh_inode(inode, &(res_p->crr_attr));
}
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ else
+ CFS_PAGEVEC_UNMAP_BUFFER(data, buffer, 0);
+#endif
(void) xdr_free(xdr_cfsrdresults_p, &res_p);
}
}
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_READ)
CFS_PAGEVEC_UNMAP(data, kvec);
#endif
sb_error_check:
@@ -560,10 +650,12 @@
int status;
#ifdef CFS_PAGEVEC
struct kvec *kvec;
- int vlen = 0;
- char async = (data->flags & RPC_TASK_ASYNC);
cfs_mntinfo_t *mip = itocmi(data->inode);
struct inode *inode = data->inode;
+ int vlen, async = (data->flags & RPC_TASK_ASYNC);
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ caddr_t buffer;
+#endif
#else
cfs_mntinfo_t *mip = itocmi(inode);
#endif
@@ -579,15 +671,23 @@
if (status)
goto sb_error_check;
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_WRITE)
CFS_PAGEVEC_MAP(data, kvec, vlen);
#endif
if (CFS_AT_SERVER(inode)) {
#ifdef CFS_PAGEVEC
/* SSI_XXX: per ssize_t byte chunk */
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ buffer = NULL;
+ CFS_PAGEVEC_MAP(data, kvec, vlen);
+ status = cfsd_write(itoc(inode)->c_hp, data->offset, kvec, vlen,
+ buffer, (unsigned long)data->count, data->stable);
+ CFS_PAGEVEC_UNMAP(data, kvec);
+#else
status = cfsd_write(itoc(inode)->c_hp, data->offset, kvec, vlen,
(unsigned long)data->count, data->stable);
+#endif
#else
status = cfsd_write(itoc(inode)->c_hp, offset, (char *)buffer,
(unsigned long)count, stable);
@@ -610,17 +710,26 @@
#ifdef CFS_PAGEVEC
args.cwa_offset = data->offset;
args.cwa_stable = data->stable;
+
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ kvec = NULL, vlen = 0;
+ CFS_PAGEVEC_MAP_BUFFER(data, buffer, 1);
+ status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
+ &kvec, vlen, buffer, (unsigned)data->count);
+ CFS_PAGEVEC_UNMAP_BUFFER(data, buffer, 0);
+#else
status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
(unsigned long)data->count, &kvec, vlen);
+#endif
#else
args.cwa_offset = offset;
args.cwa_stable = stable;
status = RCFS_WRITE(mip->mi_server, &rval, &args, &res_p,
buffer, count);
#endif
- if (status != 0 || rval != 0)
+ if (status != 0 || rval != 0) {
status = -ETIMEDOUT;
- if (status == 0) {
+ } else if (status == 0) {
status = res_p->cwr_status;
if (status == 0)
cfs_refresh_inode(inode, &res_p->cwr_attr);
@@ -628,7 +737,7 @@
}
}
-#ifdef CFS_PAGEVEC
+#if defined(CFS_PAGEVEC) && !defined(CFS_PAGEVEC_BUFFER_WRITE)
CFS_PAGEVEC_UNMAP(data, kvec);
#endif
sb_error_check:
Index: svrcfs.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/svrcfs.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- svrcfs.c 10 Oct 2008 08:10:32 -0000 1.17
+++ svrcfs.c 3 Feb 2009 06:18:12 -0000 1.18
@@ -29,6 +29,9 @@
#include <linux/module.h>
#include <linux/dcache.h>
#include <linux/namei.h>
+#ifdef ALLOC_SVRCFS_HASH_TABLE
+#include <linux/bootmem.h>
+#endif
#include <cluster/icsgen.h>
#include <cluster/nsc.h>
@@ -61,12 +64,31 @@
#define HASHSIZ 256
[...1248 lines suppressed...]
+#endif
+}
+
+#ifndef SVRCFS_KMEM_CACHE
int
svrhl_free_memory(int count, unsigned int gfp_mask)
{
@@ -2568,6 +3026,7 @@
hlist_t_free_count -= chunk;
hlist_t_free = hlistp;
UNLOCK_SPIN_LOCK(&hlist_t_free_lock);
+ mb();
hlistp = startp;
for (; chunk > 0; chunk--) {
nextp = hlistp->hl_next;
@@ -2581,3 +3040,4 @@
return hlist_t_free_count;
}
+#endif /* !SVRCFS_KMEM_CACHE */
Index: read.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/read.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- read.c 10 Oct 2008 08:10:32 -0000 1.19
+++ read.c 3 Feb 2009 06:18:12 -0000 1.20
@@ -337,7 +337,11 @@
cfs_async_handler_read(
void *args)
{
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ struct cfs_read_data *data = (struct cfs_read_data *)args;
+#else
struct cfs_read_data *data = *(struct cfs_read_data **)args;
+#endif
int status;
#ifdef CFS_PAGEVEC
unsigned int count;
@@ -487,9 +491,21 @@
/* Must pass a cfs_read_data ** because we can't move a list_head
* from one place to another, as cfs_async_queue() would.
*/
+#ifdef NSC_ASYNC_SLAB_NOFS__FLAG
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ if ((status = nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_read,
+ data, sizeof(*data),
+ NSC_ASYNC_SLEEP | NSC_ASYNC_SLAB_NOFS))) {
+#else
+ if ((status = nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_read,
+ &data, sizeof(data),
+ NSC_ASYNC_SLEEP | NSC_ASYNC_SLAB_NOFS))) {
+#endif
+#else
if ((status = nsc_async_queue(nsc_async_cfs_queue, cfs_async_handler_read,
&data, sizeof(struct cfs_read_data *),
NSC_ASYNC_SLEEP))) {
+#endif
cfs_async_read_error(&data->pages);
cfs_readdata_free(data);
@@ -497,8 +513,12 @@
}
#ifdef CFS_ASYNC_LOCAL_SYNC
} else
+#ifdef NSC_ASYNC_ARGS_ZERO_COPY
+ cfs_async_handler_read(data);
+#else
cfs_async_handler_read(&data);
#endif
+#endif
return 0;
out_bad:
Index: cfs_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_subr.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- cfs_subr.c 10 Oct 2008 08:10:31 -0000 1.23
+++ cfs_subr.c 3 Feb 2009 06:18:12 -0000 1.24
@@ -1054,7 +1054,9 @@
INIT_ATOMIC_INT(&mip->mi_sb_fsop_threads, 0);
INIT_INTR_CONDITION(&mip->mi_sb_state_cond);
INIT_INTR_CONDITION(&mip->mi_sb_down_cond);
+#ifdef SSI_CFS_SKIP
INIT_ATOMIC_INT(&mip->mi_svrcfstoks, 0);
+#endif
#ifdef SSI_XXX_NOTUSED
INIT_LIST_HEAD(&mip->lru_read);
INIT_LIST_HEAD(&mip->lru_dirty);
@@ -1192,6 +1194,7 @@
/* Detach the cnode. */
LOCK_COND_LOCK(&cnode->c_statelock);
hp = cnode->c_hp;
+ mb();
cnode->c_hp = NULL;
UNLOCK_COND_LOCK(&cnode->c_statelock);
/* Free token structure. */
@@ -1604,6 +1607,7 @@
dev_t ssidev = ((__u32 *)fhp)[0];
struct super_block *sb;
struct dentry *dentry;
+ struct svrcfstok *hp;
sb = ssi_get_super(ssidev);
if (!sb)
@@ -1650,6 +1654,9 @@
}
#endif
- return (makehp(NULL, ssidev, dentry))? : ERR_PTR(-ESTALE);
+ hp = makehp(NULL, ssidev, dentry);
+ dput(dentry);
+
+ return hp ? : ERR_PTR(-ESTALE);
}
#endif
Index: vfs.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/vfs.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- vfs.c 10 Oct 2008 08:10:32 -0000 1.27
+++ vfs.c 3 Feb 2009 06:18:12 -0000 1.28
@@ -95,11 +95,11 @@
goto nolockout;
}
- /* Lookup the name, but don't follow links */
down(&(dparent->d_inode->i_sem));
+ /* Lookup the name, but don't follow links */
dentry = lookup_hash(name, dparent);
- err = PTR_ERR(dentry);
if (IS_ERR(dentry)) {
+ err = PTR_ERR(dentry);
goto out;
}
/*
@@ -154,9 +154,8 @@
locked = TRUE;
}
dentry = lookup_hash(name, dparent);
- err = PTR_ERR(dentry);
if (IS_ERR(dentry)) {
- *hpp = (struct svrcfstok *)NULL;
+ err = PTR_ERR(dentry);
goto out;
}
/*
@@ -236,9 +235,6 @@
inode = hp->sct_ip;
- SSI_ASSERT(inode);
- SSI_ASSERT(hp->sct_dp && hp->sct_dp->d_inode);
-
#ifdef CFSD_PARANOIA
if (inode == NULL) {
dprintk("cfsd: getattr %p: NO INODE\n", hp);
@@ -246,10 +242,13 @@
}
/* Paranoid check */
- if (hp->sct_dp == NULL) {
+ if (S_ISDIR(inode->i_mode) && hp->sct_dp == NULL) {
dprintk("WARNING: cfsd: getattr %p: NO DENTRY!\n", hp);
return -EINVAL;
}
+#else
+ SSI_ASSERT(inode);
+ SSI_ASSERT(!S_ISDIR(inode->i_mode) || (hp->sct_dp && hp->sct_dp->d_inode));
#endif
_cfsd_getattr(inode, attrp);
@@ -355,14 +354,17 @@
* The access argument indicates the type of open (read/write/lock)
*/
int
+#ifdef CFSD_OPEN
+cfsd_open(struct svrcfstok *hp, int type, int access, struct file **filp)
+#else
cfsd_open(struct svrcfstok *hp, int type, int access, struct file *filp)
+#endif
{
struct dentry *dentry;
struct inode *inode;
#ifndef CFSD_OPEN
int err;
#else
- struct file *f = filp;
int flags = O_RDONLY|O_LARGEFILE, err;
#endif
@@ -441,8 +443,23 @@
DQUOT_INIT(inode);
}
- /* dentry_open() the fake struct file ... */
+ /* SSI_XXX: We don't have ex_mnt for CFS */
+ /* *filp = dentry_open(dget(dentry), mntget(hp->sct_fh->fh_export->ex_mnt), flags); */
+ *filp = dentry_open(dget(dentry), NULL, flags);
+ if (IS_ERR(*filp)) {
+ err = PTR_ERR(*filp);
+ } else if (is_shm_mmap(dentry, 1)) {
+ extern struct file_operations shm_file_operations;
+ (*filp)->f_op = &shm_file_operations;
+ if ((*filp)->f_op && (*filp)->f_op->open) {
+ err = (*filp)->f_op->open(inode, *filp);
+ if (err)
+ goto cleanup_all;
+ }
+ }
+#if 0
+ /* dentry_open() the fake struct file ... */
memset(filp, 0, sizeof(*filp));
f->f_flags = flags;
@@ -478,11 +495,24 @@
f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | O_NOOPEN);
file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
+#endif
#endif /* CFSD_OPEN */
out:
return err;
#ifdef CFSD_OPEN
cleanup_all:
+ fops_put((*filp)->f_op);
+ if ((*filp)->f_mode & FMODE_WRITE)
+ put_write_access(inode);
+ file_kill(*filp);
+ (*filp)->f_dentry = NULL;
+ /* (*filp)->f_vfsmnt = NULL; */
+ put_filp(*filp);
+ dput(dentry);
+ /* mntput(mnt); */
+ return err;
+#if 0
+cleanup_all:
fops_put(f->f_op);
if (f->f_mode & FMODE_WRITE)
put_write_access(inode);
@@ -497,6 +527,7 @@
#endif
goto out;
#endif
+#endif
}
/*
@@ -505,15 +536,7 @@
void
cfsd_close(struct file *filp)
{
- struct dentry *dentry = filp->f_dentry;
- struct inode *inode = dentry->d_inode;
-
- /* fput() fake struct file */
- if (filp->f_op && filp->f_op->release)
- filp->f_op->release(inode, filp);
- fops_put(filp->f_op);
- if (filp->f_mode & FMODE_WRITE)
- put_write_access(inode);
+ fput(filp);
}
/*
@@ -582,21 +605,26 @@
*/
int
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_READ
+cfsd_read(struct svrcfstok *hp, loff_t offset,
+ struct kvec *vec, int vlen, char *buf, unsigned long *count)
+#else
cfsd_read(struct svrcfstok *hp, loff_t offset,
struct kvec *vec, int vlen, unsigned long *count)
+#endif
#else
cfsd_read(struct svrcfstok *hp, loff_t offset, char *buf, unsigned long *count)
#endif
{
mm_segment_t oldfs;
int err;
- struct file file;
+ struct file *file;
err = cfsd_open(hp, S_IFREG, MAY_READ, &file);
if (err)
goto out;
err = -EPERM;
- if (!file.f_op->read)
+ if (!file->f_op->read)
goto out_close;
#ifdef CFS_PARANOIA
@@ -606,20 +634,26 @@
/* SSI_XXX: We should send the pid and actually do this mandatory lock
* check.
*/
- ret = locks_verify_area(FLOCK_VERIFY_READ, file.f_dentry->d_inode,
- &file, file.f_pos, *count);
+ ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
+ file, file->f_pos, *count);
#endif
#ifdef CFS_READAHEAD
/* Get readahead parameters */
if (hp->sct_ra.ra_pages)
- file.f_ra = hp->sct_ra;
+ file->f_ra = hp->sct_ra;
#endif
oldfs = get_fs(); set_fs(KERNEL_DS);
#ifdef CFS_PAGEVEC
- if (file.f_op->readv)
- err = file.f_op->readv(&file, (struct iovec __user *)vec, vlen, &offset);
+#ifdef CFS_PAGEVEC_BUFFER_READ
+ if (!vec) {
+ SSI_ASSERT(buf);
+ err = file->f_op->read(file, buf, *count, &offset);
+ } else
+#endif
+ if (file->f_op->readv)
+ err = file->f_op->readv(file, (struct iovec __user *)vec, vlen, &offset);
else {
/* Do it by hand, with file-ops. Borrowed from do_readv_writev */
err = 0;
@@ -633,7 +667,7 @@
vec++;
vlen--;
- nr = file.f_op->read(&file, base, len, &offset);
+ nr = file->f_op->read(file, base, len, &offset);
if (nr < 0) {
if (!err) err = nr;
@@ -645,25 +679,25 @@
}
}
#else
- file.f_pos = offset;
+ file->f_pos = offset;
- err = file.f_op->read(&file, buf, *count, &file.f_pos);
+ err = file->f_op->read(file, buf, *count, file->f_pos);
#endif
set_fs(oldfs);
#ifdef CFS_READAHEAD
/* Write back readahead params */
- hp->sct_ra = file.f_ra;
+ hp->sct_ra = file->f_ra;
#endif
dprintk("cfsd: read complete err=%d\n", err);
if (err >= 0) {
*count = err;
err = 0;
- dnotify_parent(file.f_dentry, DN_ACCESS);
+ dnotify_parent(file->f_dentry, DN_ACCESS);
}
out_close:
- cfsd_close(&file);
+ cfsd_close(file);
out:
return err;
}
@@ -674,21 +708,28 @@
*/
int
#ifdef CFS_PAGEVEC
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+cfsd_write(struct svrcfstok *hp, loff_t offset, struct kvec *vec, int vlen,
+ char *buf, unsigned long cnt, int stable)
+#else
cfsd_write(struct svrcfstok *hp, loff_t offset, struct kvec *vec, int vlen,
unsigned long cnt, int stable)
+#endif
#else
cfsd_write(struct svrcfstok *hp, loff_t offset, char *buf, unsigned long cnt,
int stable)
#endif
{
- struct file file;
+ struct file *file;
struct dentry *dentry;
struct inode *inode;
mm_segment_t oldfs;
ssize_t err = 0;
#ifdef CFS_GATHERWRITES
- /* SSI_XXX: breaks CHARD */
- int gathered_writes = 1;
+ int gathered_writes = ssi_isremote();
+#endif
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+ int stacked;
#endif
err = cfsd_open(hp, S_IFREG, MAY_WRITE, &file);
@@ -697,10 +738,10 @@
if (!cnt)
goto out_close;
err = -EPERM;
- if (!file.f_op->write)
+ if (!file->f_op->write)
goto out_close;
- dentry = file.f_dentry;
+ dentry = file->f_dentry;
inode = dentry->d_inode;
/*
@@ -710,7 +751,7 @@
* When gathered writes have been configured for this volume,
* flushing the data to disk is handled separately below.
*/
- if (file.f_op->fsync == 0) { /* COMMIT cannot work */
+ if (file->f_op->fsync == 0) { /* COMMIT cannot work */
stable = 2;
}
@@ -721,17 +762,16 @@
#ifdef CFS_GATHERWRITES
if (!gathered_writes)
#endif
- file.f_flags |= O_SYNC;
+ file->f_flags |= O_SYNC;
/* Write the data. */
oldfs = get_fs(); set_fs(KERNEL_DS);
#ifdef CFS_PAGEVEC
-#if defined(CFS_ASYNC_LOCAL_SYNC) && defined(CFS_FILE_WRITE_LIVELOCK_FIX)
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
/* RT: [ ssic-linux-Bugs-686748 ] Filesystem stacking deadlock.
*
* Lock ordering:
* (__cfs_file_write)
- * ->i_sem (generic_file_aio_write)
* ...
* (generic_file_buffered_write)
* (cfs_updatepage)
@@ -746,25 +786,22 @@
* ...
* ->i_sem (generic_file_writev)
*/
- if (file.f_op->writev == generic_file_writev && sem_owned(&inode->i_sem)) {
- /* Prevent further generic_file_writev() recursion. */
- current->balancing_dirty_pages = 1;
- err = generic_file_write_nolock(&file,
- (struct iovec __user *)vec,
- vlen, &offset);
- current->balancing_dirty_pages = 0;
- } else if (file.f_op->writev) {
- err = file.f_op->writev(&file,
- (struct iovec __user *)vec,
- vlen, &offset);
- } else {
- WARN_ON(file.f_op->write == generic_file_write &&
- sem_owned(&inode->i_sem));
-#else
- if (file.f_op->writev)
- err = file.f_op->writev(&file, (struct iovec __user *)vec, vlen, &offset);
- else {
+ if (sem_owned(&inode->i_sem) && !sem_flushing(&inode->i_sem)) {
+ inode->i_sem.flusher = current;
+ stacked = 1;
+ } else
+ stacked = 0;
#endif
+
+#ifdef CFS_PAGEVEC_BUFFER_WRITE
+ if (!vlen) {
+ SSI_ASSERT(!vec);
+ err = file->f_op->write(file, buf, cnt, &offset);
+ } else
+#endif
+ if (file->f_op->writev) {
+ err = file->f_op->writev(file, (struct iovec __user *)vec, vlen, &offset);
+ } else {
/* Do it by hand, with file-ops. Borrowed from do_readv_writev */
err = 0;
while (vlen > 0) {
@@ -777,7 +814,7 @@
vec++;
vlen--;
- nr = file.f_op->write(&file, base, len, &offset);
+ nr = file->f_op->write(file, base, len, &offset);
if (nr < 0) {
if (!err) err = nr;
@@ -788,15 +825,19 @@
break;
}
}
+#ifdef CFS_FILE_WRITE_LIVELOCK_FIX
+ if (stacked)
+ inode->i_sem.flusher = NULL;
+#endif
#else
- file.f_pos = offset; /* set write offset */
+ file->f_pos = offset; /* set write offset */
- err = file.f_op->write(&file, buf, cnt, &file.f_pos);
+ err = file->f_op->write(file, buf, cnt, file->f_pos);
#endif /* !CFS_PAGEVEC */
/* err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); */
set_fs(oldfs);
if (err > 0)
- dnotify_parent(file.f_dentry, DN_MODIFY);
+ dnotify_parent(file->f_dentry, DN_MODIFY);
/* clear setuid/setgid flag after write */
if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) {
@@ -851,7 +892,7 @@
if (err >= 0)
err = 0;
out_close:
- cfsd_close(&file);
+ cfsd_close(file);
out:
return err;
}
@@ -896,9 +937,10 @@
#endif
goto out_up;
dchild = lookup_hash(name, dentry);
- err = PTR_ERR(dchild);
- if (IS_ERR(dchild))
+ if (IS_ERR(dchild)) {
+ err = PTR_ERR(dchild);
goto out_up;
+ }
#ifdef SSI_XXX_NOW_GET_O_EXCL
* SSI_XXX: Like gfs in this unusual race we have problems with
@@ -1049,6 +1091,8 @@
SSI_ASSERT(!isdotent(fname->name, fname->len));
SSI_ASSERT(fname->len);
+ *hpp = NULL;
+
err = -ENOENT;
if (!fname->len)
goto out;
@@ -1066,9 +1110,10 @@
#endif
goto out_up;
dnew = lookup_hash(fname, dentry);
- err = PTR_ERR(dnew);
- if (IS_ERR(dnew))
+ if (IS_ERR(dnew)) {
+ err = PTR_ERR(dnew);
goto out_unlock;
+ }
#ifdef SSI_CFS_FROMNFS
mode = S_IALLUGO;
@@ -1157,9 +1202,10 @@
goto out_up;
dnew = lookup_hash(name, ddir);
- err = PTR_ERR(dnew);
- if (IS_ERR(dnew))
+ if (IS_ERR(dnew)) {
+ err = PTR_ERR(dnew);
goto out_up;
+ }
dold = thp->sct_dp;
dest = dold->d_inode;
@@ -1214,6 +1260,8 @@
struct svrcfstok *fhp = NULL, *thp = NULL;
dev_t dev;
+ *fhpp = *thpp = NULL;
+
fdentry = fromhp->sct_dp;
fdir = fdentry->d_inode;
@@ -1243,9 +1291,10 @@
goto out_cfserr;
odentry = lookup_hash(fname, fdentry);
- err = PTR_ERR(odentry);
- if (IS_ERR(odentry))
+ if (IS_ERR(odentry)) {
+ err = PTR_ERR(odentry);
goto out_cfserr;
+ }
err = -ENOENT;
if (!odentry->d_inode)
@@ -1264,9 +1313,10 @@
goto out_dput_old;
ndentry = lookup_hash(tname, tdentry);
- err = PTR_ERR(ndentry);
- if (IS_ERR(ndentry))
+ if (IS_ERR(ndentry)) {
+ err = PTR_ERR(ndentry);
goto out_dput_old;
+ }
#ifdef CFS_FROMNFS
err = -ENOTEMPTY;
if (ndentry == trap)
@@ -1433,9 +1483,10 @@
goto out;
rdentry = lookup_hash(name, dentry);
- err = PTR_ERR(rdentry);
- if (IS_ERR(rdentry))
+ if (IS_ERR(rdentry)) {
+ err = PTR_ERR(rdentry);
goto out;
+ }
if (!rdentry->d_inode) {
dput(rdentry);
@@ -1540,7 +1591,7 @@
struct inode *inode;
u32 *p;
int oldlen, eof, err;
- struct file file;
+ struct file *file;
struct cfs_readdir_cd cd;
err = cfsd_open(hp, S_IFDIR, MAY_READ, &file);
@@ -1552,11 +1603,11 @@
goto out_close;
err = -ENOTDIR;
- if (!file.f_op->readdir)
+ if (!file->f_op->readdir)
goto out_close;
#endif /* CFS_SKIP */
if (offset) {
- err = (int)vfs_llseek(&file, offset, 0);
+ err = (int)vfs_llseek(file, offset, 0);
if (err < 0)
goto out_close;
}
@@ -1571,7 +1622,7 @@
* readdir() is not guaranteed to fill up the entire buffer, but
* may choose to do less.
*/
- inode = file.f_dentry->d_inode;
+ inode = file->f_dentry->d_inode;
down(&inode->i_sem);
err = -ENOENT;
#ifdef SVRCFSTOK_SCT_FLAGS_NOLOCK
@@ -1588,7 +1639,7 @@
file.f_inode->i_sb->s_dev, file.f_inode->i_ino,
(int) file.f_pos, (int) oldlen, (int) cd.buflen);
*/
- err = file.f_op->readdir(&file, &cd, (filldir_t) func);
+ err = file->f_op->readdir(file, &cd, (filldir_t) func);
if (err < 0)
goto out_cfserr;
if (oldlen == cd.buflen)
@@ -1602,7 +1653,7 @@
eof = !cd.eob;
if (cd.offset)
- *cd.offset = file.f_pos;
+ *cd.offset = file->f_pos;
p = cd.buffer;
*p++ = 0; /* no more entries */
@@ -1614,7 +1665,7 @@
cd.offset? ntohl(*cd.offset) : -1);
err = 0;
out_close:
- cfsd_close(&file);
+ cfsd_close(file);
out:
return err;
@@ -1758,21 +1809,22 @@
* if it doesnt exist.
*/
droot = sbtocmi(hp->sct_sb)->mi_pfs_sb->s_root;
- dget(droot); /* needed? */
/* Lock if it isn't already locked by the caller */
if (dhp->sct_ip != droot->d_inode)
down(&(droot->d_inode->i_sem));
ddir = lookup_one_len(CFS_UNLINKDIR, droot, strlen(CFS_UNLINKDIR));
- if (IS_ERR(ddir))
+ if (IS_ERR(ddir)) {
error = PTR_ERR(ddir);
- if (!error) {
+ } else {
if (!ddir->d_inode) {
t = current;
save_cap = t->cap_effective;
+ mb();
t->cap_effective = CAP_FULL_SET;
save_fs = t->fs;
+ mb();
t->fs = copy_fs_struct(t->fs);
if (t->fs) {
t->fs->umask = 0;
@@ -1786,6 +1838,7 @@
} else if ((ddir->d_inode->i_mode & S_IALLUGO) != S_IRWXUGO) {
t = current;
save_cap = t->cap_effective;
+ mb();
t->cap_effective = CAP_FULL_SET;
down(&ddir->d_inode->i_sem);
newattrs.ia_mode = S_IRWXUGO |
@@ -1813,7 +1866,7 @@
/* Weird case he's trying to rename a delayed unlink file out
* of the .cfs_unlink directory. Hopefully this can't happen
*/
- if (ddir->d_inode == dhp->sct_ip) {
+ if (unlikely(ddir->d_inode == dhp->sct_ip)) {
error = -EINVAL;
dput(ddir);
goto out;
@@ -1834,8 +1887,19 @@
down(&(ddir->d_inode->i_sem));
new = lookup_one_len(newname, ddir, strlen(newname));
- SSI_ASSERT(!IS_ERR(new));
- SSI_ASSERT(new->d_inode == NULL);
+ /*
+ * SSI_ASSERT(!IS_ERR(new));
+ * SSI_ASSERT(new->d_inode == NULL);
+ */
+ if (unlikely(IS_ERR(new))) {
+ error = PTR_ERR(new);
+ new = NULL;
+ goto out_error;
+ }
+ if (unlikely(new->d_inode != NULL)) {
+ error = -ENOENT;
+ goto out_error;
+ }
#ifdef DEBUG
printk(KERN_DEBUG
@@ -1855,6 +1919,7 @@
dp->d_name, newname, error) );
#endif
+out_error:
up(&(ddir->d_inode->i_sem));
kfree(newname);
dput(ddir); /* done with directory, let it go */
@@ -1893,7 +1958,6 @@
#endif /* SVRCFSTOK_SCT_FLAGS_NOLOCK */
out:
- dput(droot); /* needed? */
return error;
}
@@ -1904,7 +1968,7 @@
* with linkit passed as TRUE. This is the only scenario in which it
* would be clean to undo.
*/
-static void
+static void __deprecated
cfs_delayedunlink_undo(
struct inode *tip,
char *tnm,
@@ -1916,7 +1980,6 @@
int error;
droot = sbtocmi(hp->sct_sb)->mi_pfs_sb->s_root;
- dget(droot); /* needed? */
/* Lock if it isn't already locked by the caller */
if (dhp->sct_ip != droot->d_inode)
@@ -1928,7 +1991,6 @@
if (dhp->sct_ip != droot->d_inode)
up(&(droot->d_inode->i_sem));
- dput(droot); /* needed? */
#ifdef DEBUG
if (error) {
------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com