[SSI] openssi/kernel/cluster/ssi/cfs cfs_ipcshm.c, 1.19, 1.20 cfs_mnthooks.c, 1.22, 1.23 cfs_subr.c, 1.24, 1.25 cfsproc.c, 1.30, 1.31 dir.c, 1.24, 1.25 inode.c, 1.57, 1.58 svrcfs.c, 1.21, 1.22 vfs.c, 1.29, 1.30

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-serv23689/cluster/ssi/cfs

Modified Files:
      Tag: OPENSSI-FC
	cfs_ipcshm.c cfs_mnthooks.c cfs_subr.c cfsproc.c dir.c inode.c 
	svrcfs.c vfs.c 
Log Message:
CFS:
- Fix possible server token table hash key race with PFS file handle data.
- Further avoid ssi_get_super() to reduce contention. We don't cross mount points.
- Switch to Linux get_empty_filp() to get unused file structure for svrcfstok structure.
- Regression:
  - Possible inode leak when out of memory doing export ops get_dentry. (#ifdef CFS_EXPORT_OPS)
  - Possibly missed drop_super() while performing export ops get_dentry. (#ifdef CFS_FH_TO_DENTRY_ANON)

IPC:
- Fix uninitialized spin lock in kern_ipc_perm structure (in SSI context).
- Fix uninitialized linked list pointers in unixnm_svr_entry and unixnm_cache_entry structures.
- SHM dentry lookup bug fixes:
  - Error -ENOENT in CFS (negative dentry) due to not validating against PFS.
  - Fix SHM negative dentry lookup could cause future memory corruption.
    - Did not increment inode count when instantiating dentry.
    - Bad dentry reference count side-effect due to incorrect return value for Linux namespace architecture.

IPVS:
- Fix uninitialized linked list pointers in ipvs_dirinfo and portweight_list structures.

SSI:
- Fix dentry race calling __d_path() outside dcache lock. (#ifdef SSI_DCACHE_RACE_FIX)
- Fix uninitialized linked list pointers in structures rmtfb_cmn, ssidev_hash, fifonm_svr_entry, fifonm_cache_entry, and ssipty_svr_
entry.

VPROC:
- Fix possibly missed drop_super() during process migration exporting of file descriptors.
- Fix partially initialized proc_root_readdir_cookie structure.
- semundo_load_msg() handle process sysvsem.undo_list->proc_list race take two. (#ifdef VPROC_UNLOAD_SETSCHED_SMP)
- Regression:
  - Process migration traversing rmtfb path while importing SHM fd's; caused by fb_svrnode macro. (#ifdef REOP_EXPORT_PATH_SVRNODE)


Index: cfs_ipcshm.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_ipcshm.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- cfs_ipcshm.c	8 Feb 2009 02:44:41 -0000	1.19
+++ cfs_ipcshm.c	19 Feb 2009 08:01:01 -0000	1.20
@@ -68,7 +68,6 @@
 		int shmflg)
 {
 	struct shmid_kernel_svr *svr_shm;
-	struct dentry *de;
 	nsc_nodelist_t *nl;
 	int err = 0;
 
@@ -78,7 +77,6 @@
 	if (!svr_shm)
 		return -ENOMEM;
 
-	de = shp->shm_file->f_dentry;
 	svr_shm->shm_id = newid;
 	svr_shm->shm_segsz = size;
 	svr_shm->shm_cprid = current->pid;
@@ -94,7 +92,8 @@
 	NSC_NODELIST_SET1(nl, this_node);
 	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);
+			ssidev_get_s_ssidev(shm_mnt->mnt_sb, FALSE),
+			shp->shm_file->f_dentry);
 	SSI_ASSERT(svr_shm->shm_svr);
 	if (shm_svr_addid(svr_shm) < 0) {
 		printk("failed to add shm svr\n");
@@ -113,7 +112,6 @@
 	struct shmid_kernel_svr *shmsvr = NULL;
 	struct inode *ip = NULL;
 	struct qstr this;
-	struct dentry *newde;
 	struct dentry *de;
 
 	if (server == this_node) {
@@ -132,14 +130,13 @@
 		ip = cfs_hpget(cfs_shm_sb, shmsvr->shm_svr);
 		if (ip == NULL)
 			return NULL;
-		newde = shmsvr->shm_svr->sct_dp;
-		memcpy(&this, &(newde->d_name), sizeof(struct qstr));
+		memcpy(&this, &(shmsvr->shm_svr->sct_dp->d_name), sizeof(struct qstr));
 		de = d_alloc(cfs_shm_sb->s_root, &this);
-		de->d_sb = ip->i_sb;
-		de->d_parent = cfs_shm_sb->s_root;
 #ifdef CFS_IPCSHM_DENTRY
 		d_add(de, ip);
 #else
+		de->d_sb = ip->i_sb;
+		de->d_parent = cfs_shm_sb->s_root;
 		d_instantiate(de, ip);
 		d_rehash(shmsvr->shm_svr->sct_dp);
 #endif
@@ -199,8 +196,10 @@
 
 			de = d_alloc(cfs_node_sb->s_root, &this);
 			ip->i_size = size;
+#ifndef CFS_IPCSHM_DENTRY
 			de->d_sb = ip->i_sb;
 			de->d_parent = cfs_node_sb->s_root;
+#endif
 			d_instantiate(de, ip);
 #ifdef JUNK
 			shp->shm_file->f_dentry = de;
@@ -271,61 +270,59 @@
 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);
 }
 
+struct inode *
+shm_svr_get_inode(int id)
+{
+	struct shmid_kernel_svr *shmsvr = shm_svr_get(id);
+	return shmsvr ? shmsvr->shm_svr->sct_ip : NULL;
+}
+
 struct dentry *
 shmem_svr_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
 	struct inode *inode;
-	char key[16];
-	int real_key;
 	long id;
 	clusternode_t svr;
        	int size;
-	struct shmid_kernel_svr *shmp;
+	int real_key;
 
-	if (!is_shm_mmap(dentry, 0)) {
+	if (!is_shm_mmap(dentry, 1)) {
 #ifdef CONFIG_TMPFS
 		d_add(dentry, NULL);
 #endif
 		return NULL;
 	}
 	id = svr = size = 0;
-	strcpy(key, dentry->d_name.name+4);
-	sscanf(key, "%x", &real_key);
+	sscanf(dentry->d_name.name, "SYSV%x", &real_key);
 	cli_ipcname_getid(NAME_SERVICE_SHM, real_key, 0, &id, &svr, 
 						ssi_get_localview(), &size);
-	shmp = (struct shmid_kernel_svr *)shm_svr_get(id);
-	inode = (shmp->shm_svr)->sct_ip;
-	d_add(dentry, inode);
-	return dentry;
-}
+	inode = shm_svr_get_inode(id);
+	if (!inode || !igrab(inode))
+		return ERR_PTR(-EACCES);
 
-struct inode *
-shm_svr_get_inode(int id)
-{
-	struct shmid_kernel_svr *shmsvr = shm_svr_get(id);
-	return shmsvr ? shmsvr->shm_svr->sct_ip : NULL;
+	return d_splice_alias(inode, dentry);
 }
 
-
 int
 is_shm_mmap(struct dentry *de, int is_pfs)
 {
 	int i;
 
 	if (!strncmp(de->d_name.name, "SYSV", 4)) {
-		if (is_pfs) {
-			if (is_shmem_inode(de->d_inode))
-				return 1;
-		}
+		if (is_pfs && de->d_inode && is_shmem_inode(de->d_inode))
+			return 1;
+
 		for (i=1; i <= (NSC_MAX_NODE_VALUE + 1); i++) {
-			if (cfs_shm_node_mnts[i] &&
-				(de->d_sb == (cfs_shm_node_mnts[i])->mnt_sb))
+			if (!cfs_shm_node_mnts[i])
+				continue;
+			if (is_pfs) { /* negative lookup */
+				if (de->d_sb == (cfs_shm_node_mnts[i])->mnt_root->d_sb)
+					return 1;
+			} else if (de->d_sb == (cfs_shm_node_mnts[i])->mnt_sb)
 				return 1;
 		}
 	}

Index: inode.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/inode.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- inode.c	3 Feb 2009 06:18:12 -0000	1.57
+++ inode.c	19 Feb 2009 08:01:01 -0000	1.58
@@ -2114,6 +2114,7 @@
 {
 	__u32 *data = vobjp;
 	struct inode *inode;
+	struct dentry *dentry;
 
 	/*
 	 * Attempt to find the inode.
@@ -2141,7 +2142,12 @@
 	/* now to find a dentry.
 	 * If possible, get a well-connected one
 	 */
-	return d_alloc_anon(inode) ? : ERR_PTR(-ENOMEM);
+	dentry = d_alloc_anon(inode);
+	if (!dentry) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	} else
+		return dentry;
 }
 #endif /* CFS_EXPORT_OPS */
 

Index: dir.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/dir.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- dir.c	3 Feb 2009 06:18:12 -0000	1.24
+++ dir.c	19 Feb 2009 08:01:01 -0000	1.25
@@ -452,8 +452,7 @@
  */
 static int cfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
-	struct dentry	*dentry = filp->f_dentry;
-	struct inode	*inode = dentry->d_inode;
+	struct inode *inode = filp->f_dentry->d_inode;
 	cfs_mntinfo_t *mip = itocmi(inode);
 	cfs_readdir_descriptor_t my_desc,
 			*desc = &my_desc;

Index: cfsproc.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfsproc.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- cfsproc.c	7 Feb 2009 04:19:43 -0000	1.30
+++ cfsproc.c	19 Feb 2009 08:01:01 -0000	1.31
@@ -115,14 +115,15 @@
 	SSI_ASSERT(dentry->d_inode == inode);
 
 	error = -ENOMEM;
-	filp = (struct file *) kzmalloc(sizeof(*filp), GFP_KERNEL);
+	//filp = (struct file *) kzmalloc(sizeof(*filp), GFP_KERNEL);
+	filp = get_empty_filp();
 	if (!filp)
 		goto out;
 
 	filp->f_op    = fops_get(inode->i_fop);
-	atomic_set(&filp->f_count, 1);
+	//atomic_set(&filp->f_count, 1);
 	filp->f_dentry = dget(dentry);
-	filp->f_vfsmnt = NULL;		/* SSI_XXX: Do I need something? */
+	/* filp->f_vfsmnt = NULL; */		/* SSI_XXX: Do I need something? */
 
 	filp->f_flags = O_RDONLY|O_LARGEFILE;
 	filp->f_mode  = FMODE_READ;
@@ -131,9 +132,12 @@
 	if (filp->f_op && filp->f_op->open) {
 		error = filp->f_op->open(inode, filp);
 		if (error) {
+			fput(filp);
+#if 0
 			dput(filp->f_dentry);
 			fops_put(filp->f_op);
 			kfree(filp);
+#endif
 			goto out;
 		}
 	}
@@ -144,11 +148,14 @@
 
 printk(KERN_WARNING "cfs_setup_sct_fp: Found sct_fp, must undo mine\n");
 		/* Someone else attached an fp before we could */
+		fput(filp);
+#if 0
 		if (filp->f_op && filp->f_op->release)
 			filp->f_op->release(hp->sct_ip, filp);
 		dput(filp->f_dentry);
 		fops_put(filp->f_op);
 		kfree(filp);
+#endif
 	} else {
 		hp->sct_fp = filp;
 		UNLOCK_COND_LOCK(&hp->sct_statelock);
@@ -1899,7 +1906,6 @@
 		goto out;
 	}
 
-	/* SSI_XXX: Not using sa_datasync at this point */
 	cfsd_sync_dir(hp->sct_dp, args->sa_datasync);
 
 	HASH_RELE(hp);

Index: cfs_mnthooks.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_mnthooks.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- cfs_mnthooks.c	20 Apr 2008 05:49:21 -0000	1.22
+++ cfs_mnthooks.c	19 Feb 2009 08:01:01 -0000	1.23
@@ -347,8 +347,14 @@
 	if (!(page = __get_free_page(GFP_KERNEL)))
 		BUG();
 
+#ifdef SSI_DCACHE_RACE_FIX
+	spin_lock(&dcache_lock);
+#endif
 	args.dir_name =
 	    __d_path(nd->dentry, nd->mnt, NULL, NULL, (char *)page, PAGE_SIZE);
+#ifdef SSI_DCACHE_RACE_FIX
+	spin_unlock(&dcache_lock);
+#endif
 
 	args.flags = flags;
 	args.server = this_node;
@@ -754,8 +760,7 @@
 {
 	svrhold_list_t new_hold_list;
 	struct super_block *sb = mnt->mnt_sb;
-	struct dentry *root_dentry = sb->s_root;
-	struct inode *root = root_dentry->d_inode;
+	struct inode *root = sb->s_root->d_inode;
 	struct svrcfstok *hp;
 	static char cfs_type[] = "cfs";
 	struct cfs_mount_data *cmdp;

Index: svrcfs.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/svrcfs.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- svrcfs.c	12 Feb 2009 03:13:13 -0000	1.21
+++ svrcfs.c	19 Feb 2009 08:01:01 -0000	1.22
@@ -184,11 +184,7 @@
 /*
  * Return the hash index for the specified file-handle+token-type.
  */
-#ifdef SSI_1_2
 static int
-#else
-static u_long
-#endif
 svrhash(cfhandle_t *fhp)
 {
 	u_char *fhpp;
@@ -196,7 +192,8 @@
 	int i;
 
 	fhpp = (u_char *)fhp;
-	i = sizeof(cfhandle_t);
+	/* i = sizeof(cfhandle_t); */
+	i = sizeof(__u32) * 4; /* ssidev,size,type,ino */
 	fhsum = 0;
 	while (i-- > 0)
 		fhsum += *fhpp++;
@@ -233,16 +230,12 @@
 #else
 	struct svrcfstok *hp;
 #endif
-#ifdef SSI_1_2
 	int hash = svrhash(fhp);
-#else
-	u_long hash = svrhash(fhp);
-#endif
 #ifdef RCU_CFSTOK_TABLE
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(hp, pos, &svrcfs_hash_table[hash], sct_hlist) {
 		if (memcmp((caddr_t)fhp, (caddr_t)&(hp->sct_fh),
-		    sizeof(hp->sct_fh)))
+		    sizeof(__u32)*4)) /* ssidev,size,type,ino */
 			continue;
 		found = hash_hold_and_check(hp);
 		break;
@@ -333,11 +326,7 @@
 #endif
 #endif
 	object_t obj;
-#ifdef SSI_1_2
 	int hash;
-#else
-	u_long hash;
-#endif
 
 	while (1) {
 #ifndef RCU_CFSTOK_TABLE
@@ -627,11 +616,7 @@
 		if (hp->sct_prev)
 			hp->sct_prev->sct_next = hp->sct_next;
 		else {/* Reset head pointer if needed */
-#ifdef SSI_1_2
 			int hash = svrhash(&(hp->sct_fh));
-#else
-			u_long hash = svrhash(&(hp->sct_fh));
-#endif
 			svrcfs_hash_table[hash] = hp->sct_next;
 		}
 		if (hp->sct_next)
@@ -2923,6 +2908,8 @@
 #ifdef __KERNEL__
 	/* Must do this before iput/dput below, because they weren't held */
 	if (hp->sct_fp != NULL) {
+		fput(hp->sct_fp);
+#if 0
 		struct file *filp = hp->sct_fp;
 
 		if (filp->f_op && filp->f_op->release)
@@ -2930,6 +2917,7 @@
 		dput(filp->f_dentry);
 		fops_put(filp->f_op);
 		kfree(filp);
+#endif
 	}
 
 	if (hp->sct_dp != NULL) {

Index: cfs_subr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/cfs_subr.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- cfs_subr.c	3 Feb 2009 06:18:12 -0000	1.24
+++ cfs_subr.c	19 Feb 2009 08:01:01 -0000	1.25
@@ -1654,8 +1654,9 @@
 	}
 #endif
 
- 	hp = makehp(NULL, ssidev, dentry);
+ 	hp = makehp(sb, ssidev, dentry);
  	dput(dentry);
+	drop_super(sb);
 
  	return hp ? : ERR_PTR(-ESTALE);
 }

Index: vfs.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/cfs/vfs.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- vfs.c	12 Feb 2009 03:13:13 -0000	1.29
+++ vfs.c	19 Feb 2009 08:01:01 -0000	1.30
@@ -175,7 +175,7 @@
 	 */
 	err = 0;
 	dev = (dev_t)*(__u32 *)(&dhp->sct_fh);
-	*hpp = makehp(NULL, dev, dentry);
+	*hpp = makehp(dhp->sct_sb, dev, dentry);
 
 out:
 	if (!IS_ERR(dentry))
@@ -970,7 +970,7 @@
 			goto out_up;
 		}
 		err = 0;
-		*hpp = makehp(NULL, dev, dchild);
+		*hpp = makehp(dhp->sct_sb, dev, dchild);
 		goto out_up;
 	}
 
@@ -1007,7 +1007,7 @@
 	dhp->sct_vn++;
 #endif
 
-	*hpp = makehp(NULL, dev, dchild);
+	*hpp = makehp(dhp->sct_sb, dev, dchild);
 
 #ifdef CFS_ONLY_REMOTE_IS_CHARD
 	if (sbtocmi(dhp->sct_sb)->mi_flags & MI_CHARD && ssi_isremote())
@@ -1160,7 +1160,7 @@
 #endif
 
 	dev = (dev_t)*(__u32 *)(&dhp->sct_fh);
-	*hpp = makehp(NULL, dev, dnew);
+	*hpp = makehp(dhp->sct_sb, dev, dnew);
 
 out_unlock:
 	if (!IS_ERR(dnew))
@@ -1495,7 +1495,7 @@
 	}
 
 	dev = (dev_t)*(__u32 *)(&dhp->sct_fh);
-	hp = makehp(NULL, dev, rdentry);
+	hp = makehp(dhp->sct_sb, dev, rdentry);
 
 #ifdef SVRCFSTOK_SCT_FLAGS_NOLOCK
 	if (test_bit(CFS_DELAYUNLNK, &hp->sct_flags)) {


------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.