1
linux/fs
Patrick Caulfield ac33d07105 [DLM] Clean up lowcomms
This fixes up most of the things pointed out by akpm and Pavel Machek
with comments below indicating why some things have been left:

Andrew Morton wrote:
>
>> +static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc)
>> +{
>> +	struct nodeinfo *ni;
>> +	int r;
>> +	int n;
>> +
>> +	down_read(&nodeinfo_lock);
>
> Given that this function can sleep, I wonder if `alloc' is useful.
>
> I see lots of callers passing in a literal "0" for `alloc'.  That's in fact
> a secret (GFP_ATOMIC & ~__GFP_HIGH).  I doubt if that's what you really
> meant.  Particularly as the code could at least have used __GFP_WAIT (aka
> GFP_NOIO) which is much, much more reliable than "0".  In fact "0" is the
> least reliable mode possible.
>
> IOW, this is all bollixed up.

When 0 is passed into nodeid2nodeinfo the function does not try to allocate a
new structure at all. it's an indication that the caller only wants the nodeinfo
struct for that nodeid if there actually is one in existance.
I've tidied the function itself so it's more obvious, (and tidier!)

>> +/* Data received from remote end */
>> +static int receive_from_sock(void)
>> +{
>> +	int ret = 0;
>> +	struct msghdr msg;
>> +	struct kvec iov[2];
>> +	unsigned len;
>> +	int r;
>> +	struct sctp_sndrcvinfo *sinfo;
>> +	struct cmsghdr *cmsg;
>> +	struct nodeinfo *ni;
>> +
>> +	/* These two are marginally too big for stack allocation, but this
>> +	 * function is (currently) only called by dlm_recvd so static should be
>> +	 * OK.
>> +	 */
>> +	static struct sockaddr_storage msgname;
>> +	static char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
>
> whoa.  This is globally singly-threaded code??

Yes. it is only ever run in the context of dlm_recvd.
>>
>> +static void initiate_association(int nodeid)
>> +{
>> +	struct sockaddr_storage rem_addr;
>> +	static char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
>
> Another static buffer to worry about.  Globally singly-threaded code?

Yes. Only ever called by dlm_sendd.

>> +
>> +/* Send a message */
>> +static int send_to_sock(struct nodeinfo *ni)
>> +{
>> +	int ret = 0;
>> +	struct writequeue_entry *e;
>> +	int len, offset;
>> +	struct msghdr outmsg;
>> +	static char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
>
> Singly-threaded?

Yep.

>>
>> +static void dealloc_nodeinfo(void)
>> +{
>> +	int i;
>> +
>> +	for (i=1; i<=max_nodeid; i++) {
>> +		struct nodeinfo *ni = nodeid2nodeinfo(i, 0);
>> +		if (ni) {
>> +			idr_remove(&nodeinfo_idr, i);
>
> Didn't that need locking?

Not. it's only ever called at DLM shutdown after all the other threads
have been stopped.

>>
>> +static int write_list_empty(void)
>> +{
>> +	int status;
>> +
>> +	spin_lock_bh(&write_nodes_lock);
>> +	status = list_empty(&write_nodes);
>> +	spin_unlock_bh(&write_nodes_lock);
>> +
>> +	return status;
>> +}
>
> This function's return value is meaningless.  As soon as the lock gets
> dropped, the return value can get out of sync with reality.
>
> Looking at the caller, this _might_ happen to be OK, but it's a nasty and
> dangerous thing.  Really the locking should be moved into the caller.

It's just an optimisation to allow the caller to schedule if there is no work
to do. if something arrives immediately afterwards then it will get picked up
when the process re-awakes (and it will be woken by that arrival).

The 'accepting' atomic has gone completely. as Andrew pointed out it didn't
really achieve much anyway. I suspect it was a plaster over some other
startup or shutdown bug to be honest.


Signed-off-by: Patrick Caulfield <pcaulfie@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Cc: Andrew Morton <akpm@osdl.org>
Cc: Pavel Machek <pavel@ucw.cz>
2006-12-07 09:25:13 -05:00
..
9p
adfs
affs
afs
autofs [PATCH] autofs4: panic after mount fail 2006-11-14 09:09:27 -08:00
autofs4 [PATCH] autofs4: panic after mount fail 2006-11-14 09:09:27 -08:00
befs
bfs
cifs [CIFS] Fix minor problem with previous patch 2006-11-09 21:25:37 +00:00
coda
configfs
cramfs
debugfs [PATCH] debugfs: add header file 2006-11-25 13:28:33 -08:00
devpts
dlm [DLM] Clean up lowcomms 2006-12-07 09:25:13 -05:00
ecryptfs [PATCH] ecryptfs: fix crypto_alloc_blkcipher() error check 2006-11-28 17:26:50 -08:00
efs
exportfs
ext2
ext3
ext4
fat [PATCH] fat: add fat_getattr() 2006-11-16 11:43:38 -08:00
freevxfs
fuse [PATCH] fuse: fix Oops in lookup 2006-11-25 13:28:33 -08:00
gfs2 [GFS2] Change gfs2_fsync() to use write_inode_now() 2006-12-07 09:13:14 -05:00
hfs [PATCH] hfs_fill_super returns success even if no root inode 2006-11-16 11:43:38 -08:00
hfsplus
hostfs
hpfs
hppfs
hugetlbfs [PATCH] hugetlb: prepare_hugepage_range check offset too 2006-11-14 09:09:27 -08:00
isofs
jbd
jbd2
jffs
jffs2
jfs
lockd [PATCH] sysctl: implement CTL_UNNUMBERED 2006-11-06 01:46:23 -08:00
minix
msdos [PATCH] fat: add fat_getattr() 2006-11-16 11:43:38 -08:00
ncpfs
nfs [PATCH] sysctl: implement CTL_UNNUMBERED 2006-11-06 01:46:23 -08:00
nfs_common
nfsd [PATCH] nfsd: fix spurious error return from nfsd_create in async case 2006-11-08 18:29:25 -08:00
nls
ntfs
ocfs2
openpromfs
partitions
proc [PATCH] mounstats NULL pointer dereference 2006-11-25 13:28:33 -08:00
qnx4
ramfs
reiserfs [PATCH] reiserfs: fmt bugfix 2006-11-25 13:28:33 -08:00
romfs
smbfs
sysfs
sysv
udf
ufs
vfat [PATCH] fat: add fat_getattr() 2006-11-16 11:43:38 -08:00
xfs [XFS] Stale the correct inode when freeing clusters. 2006-11-21 18:55:33 +11:00
aio.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c
binfmt_elf.c
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
binfmt_som.c
bio.c
block_dev.c
buffer.c
char_dev.c
compat_ioctl.c
compat.c
dcache.c
dcookies.c
direct-io.c
dnotify.c
dquot.c
drop_caches.c
eventpoll.c
exec.c
fcntl.c
fifo.c
file_table.c
file.c
filesystems.c
fs-writeback.c
generic_acl.c
inode.c
inotify_user.c
inotify.c
internal.h
ioctl.c
ioprio.c
Kconfig [PATCH] AFS: Amend the AFS configuration options 2006-11-16 11:43:38 -08:00
Kconfig.binfmt
libfs.c
locks.c
Makefile
mbcache.c
mpage.c
namei.c
namespace.c
nfsctl.c
no-block.c
open.c
pipe.c
pnode.c
pnode.h
posix_acl.c
quota_v1.c
quota_v2.c
quota.c
read_write.c
read_write.h
readdir.c
select.c
seq_file.c
splice.c [PATCH] splice: fix problem introduced with inode diet 2006-11-04 08:45:39 -08:00
stat.c
super.c
sync.c
utimes.c
xattr_acl.c
xattr.c [PATCH] Fix user.* xattr permission check for sticky dirs 2006-11-03 12:27:59 -08:00