summaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsfs.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* Merge branch 'for-next' of ↵Linus Torvalds2011-10-281-1/+1
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/hch/vfs-queue * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/vfs-queue: (21 commits) leases: fix write-open/read-lease race nfs: drop unnecessary locking in llseek ext4: replace cut'n'pasted llseek code with generic_file_llseek_size vfs: add generic_file_llseek_size vfs: do (nearly) lockless generic_file_llseek direct-io: merge direct_io_walker into __blockdev_direct_IO direct-io: inline the complete submission path direct-io: separate map_bh from dio direct-io: use a slab cache for struct dio direct-io: rearrange fields in dio/dio_submit to avoid holes direct-io: fix a wrong comment direct-io: separate fields only used in the submission path from struct dio vfs: fix spinning prevention in prune_icache_sb vfs: add a comment to inode_permission() vfs: pass all mask flags check_acl and posix_acl_permission vfs: add hex format for MAY_* flag values vfs: indicate that the permission functions take all the MAY_* flags compat: sync compat_stats with statfs. vfs: add "device" tag to /proc/self/mountstats cleanup: vfs: small comment fix for block_invalidatepage ... Fix up trivial conflict in fs/gfs2/file.c (llseek changes)
| * vfs: do (nearly) lockless generic_file_llseekAndi Kleen2011-10-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The i_mutex lock use of generic _file_llseek hurts. Independent processes accessing the same file synchronize over a single lock, even though they have no need for synchronization at all. Under high utilization this can cause llseek to scale very poorly on larger systems. This patch does some rethinking of the llseek locking model: First the 64bit f_pos is not necessarily atomic without locks on 32bit systems. This can already cause races with read() today. This was discussed on linux-kernel in the past and deemed acceptable. The patch does not change that. Let's look at the different seek variants: SEEK_SET: Doesn't really need any locking. If there's a race one writer wins, the other loses. For 32bit the non atomic update races against read() stay the same. Without a lock they can also happen against write() now. The read() race was deemed acceptable in past discussions, and I think if it's ok for read it's ok for write too. => Don't need a lock. SEEK_END: This behaves like SEEK_SET plus it reads the maximum size too. Reading the maximum size would have the 32bit atomic problem. But luckily we already have a way to read the maximum size without locking (i_size_read), so we can just use that instead. Without i_mutex there is no synchronization with write() anymore, however since the write() update is atomic on 64bit it just behaves like another racy SEEK_SET. On non atomic 32bit it's the same as SEEK_SET. => Don't need a lock, but need to use i_size_read() SEEK_CUR: This has a read-modify-write race window on the same file. One could argue that any application doing unsynchronized seeks on the same file is already broken. But for the sake of not adding a regression here I'm using the file->f_lock to synchronize this. Using this lock is much better than the inode mutex because it doesn't synchronize between processes. => So still need a lock, but can use a f_lock. This patch implements this new scheme in generic_file_llseek. I dropped generic_file_llseek_unlocked and changed all callers. Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
* | Merge branch 'cifs-3.2' of git://git.samba.org/jlayton/linux into temp-3.2-jeffSteve French2011-10-201-1/+1
|\ \
| * | cifs: allow cifs_max_pending to be readable under /sys/module/cifs/parametersJeff Layton2011-10-191-1/+1
| | | | | | | | | | | | Signed-off-by: Jeff Layton <jlayton@redhat.com>
* | | [CIFS] Show nostrictsync and noperm mount options in /proc/mountsSteve French2011-10-201-0/+4
|/ / | | | | | | | | | | | | | | | | Add support to print nostrictsync and noperm mount options in /proc/mounts for shares mounted with these options. (cleanup merge conflict in Sachin's original patch) Suggested-by: Sachin Prabhu <sprabhu@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
* | CIFS: Move byte range lock list from fd to inodePavel Shilovsky2011-10-141-1/+2
| | | | | | | | | | | | | | that let us do local lock checks before requesting to the server. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <smfrench@gmail.com>
* | add new module parameter 'enable_oplocks'Steve French2011-10-131-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Thus spake Jeff Layton: "Making that a module parm would allow you to set that parameter at boot time without needing to add special startup scripts. IMO, all of the procfile "switches" under /proc/fs/cifs should be module parms instead." This patch doesn't alter the default behavior (Oplocks are enabled by default). To disable oplocks when loading the module, use modprobe cifs enable_oplocks=0 (any of '0' or 'n' or 'N' conventions can be used). To disable oplocks at runtime using the new interface, use echo 0 > /sys/module/cifs/parameters/enable_oplocks The older /proc/fs/cifs/OplockEnabled interface will be deprecated after two releases. A subsequent patch will add an warning message about this deprecation. Changes since v2: - make enable_oplocks a 'bool' Changes since v1: - eliminate the use of extra variable by renaming the old one to enable_oplocks and make it an 'int' type. Reported-by: Alexander Swen <alex@swen.nu> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> Signed-off-by: Steve French <smfrench@gmail.com>
* | cifs: Fix typo 'CIFS_NFSD_EXPORT'Paul Bolle2011-10-131-2/+2
| | | | | | | | | | | | | | | | It should be 'CONFIG_CIFS_NFSD_EXPORT'. No-one noticed because that symbol depends on BROKEN. Signed-off-by: Paul Bolle <pebolle@tiscali.nl> Signed-off-by: Steve French <smfrench@gmail.com>
* | cifs: get rid of unused xid in cifs_get_rootJeff Layton2011-10-131-3/+0
| | | | | | | | | | Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
* | cifs: Display strictcache mount option in /proc/mountsSachin Prabhu2011-10-111-0/+2
|/ | | | | | | | | | | Commit d39454ffe4a3c85428483b8a8a8e5e797b6363d5 adds a strictcache mount option. This patch allows the display of this mount option in /proc/mounts when listing shares mounted with the strictcache mount option. Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
* CIFS: Fix ERR_PTR dereference in cifs_get_rootPavel Shilovsky2011-09-201-4/+6
| | | | | | | | move it to the beginning of the loop. Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: cope with negative dentries in cifs_get_rootJeff Layton2011-08-051-0/+4
| | | | | | | | | | | | | | | | | | The loop around lookup_one_len doesn't handle the case where it might return a negative dentry, which can cause an oops on the next pass through the loop. Check for that and break out of the loop with an error of -ENOENT if there is one. Fixes the panic reported here: https://bugzilla.redhat.com/show_bug.cgi?id=727927 Reported-by: TR Bentley <home@trarbentley.net> Reported-by: Iain Arnell <iarnell@gmail.com> Cc: Al Viro <viro@ZenIV.linux.org.uk> Cc: stable@kernel.org Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: simplify refcounting for oplock breaksJeff Layton2011-07-311-18/+0
| | | | | | | | | | | | | | | | | Currently, we take a sb->s_active reference and a cifsFileInfo reference when an oplock break workqueue job is queued. This is unnecessary and more complicated than it needs to be. Also as Al points out, deactivate_super has non-trivial locking implications so it's best to avoid that if we can. Instead, just cancel any pending oplock breaks for this filehandle synchronously in cifsFileInfo_put after taking it off the lists. That should ensure that this job doesn't outlive the structures it depends on. Reported-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* fs: handle SEEK_HOLE/SEEK_DATA properly in all fs's that define their own llseekJosef Bacik2011-07-211-2/+5
| | | | | | | | | | | | This converts everybody to handle SEEK_HOLE/SEEK_DATA properly. In some cases we just return -EINVAL, in others we do the normal generic thing, and in others we're simply making sure that the properly due-dilligence is done. For example in NFS/CIFS we need to make sure the file size is update properly for the SEEK_HOLE and SEEK_DATA case, but since it calls the generic llseek stuff itself that is all we have to do. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ->permission() sanitizing: don't pass flags to ->permission()Al Viro2011-07-201-1/+1
| | | | | | not used by the instances anymore. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ->permission() sanitizing: don't pass flags to generic_permission()Al Viro2011-07-201-1/+1
| | | | | | | redundant; all callers get it duplicated in mask & MAY_NOT_BLOCK and none of them removes that bit. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* kill check_acl callback of generic_permission()Al Viro2011-07-201-1/+1
| | | | | | | its value depends only on inode and does not change; we might as well store it in ->i_op->check_acl and be done with that. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* Fix cifs_get_root()Al Viro2011-07-181-71/+29
| | | | | | | | | | Add missing ->i_mutex, convert to lookup_one_len() instead of (broken) open-coded analog, cope with getting something like a//b as relative pathname. Simplify the hell out of it, while we are there... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Reviewed-by: Jeff Layton <jlayton@redhat.com>
* cifs: factor smb_vol allocation out of cifs_setup_volume_infoJeff Layton2011-07-081-3/+3
| | | | | | Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Pavel Shilovsky <piastryyy@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: have cifs_cleanup_volume_info not take a double pointerJeff Layton2011-07-061-1/+1
| | | | | | | | | ...as that makes for a cumbersome interface. Make it take a regular smb_vol pointer and rely on the caller to zero it out if needed. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Pavel Shilovsky <piastryyy@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: propagate errors from cifs_get_root() to mount(2)Al Viro2011-06-251-7/+5
| | | | | | | | ... instead of just failing with -EINVAL Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: tidy cifs_do_mount() up a bitAl Viro2011-06-251-22/+22
| | | | | | Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: more breakage on mount failuresAl Viro2011-06-251-7/+4
| | | | | | | | | | if cifs_get_root() fails, we end up with ->mount() returning NULL, which is not what callers expect. Moreover, in case of superblock reuse we end up leaking a superblock reference... Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: close sget() racesAl Viro2011-06-251-3/+9
| | | | | | | | have ->s_fs_info set by the set() callback passed to sget() Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: pull freeing mountdata/dropping nls/freeing cifs_sb into cifs_umount()Al Viro2011-06-251-14/+1
| | | | | | | | | all callers of cifs_umount() proceed to do the same thing; pull it into cifs_umount() itself. Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: move cifs_umount() call into ->kill_sb()Al Viro2011-06-251-18/+1
| | | | | | | | | | | instead of calling it manually in case if cifs_read_super() fails to set ->s_root, just call it from ->kill_sb(). cifs_put_super() is gone now *and* we have cifs_sb shutdown and destruction done after the superblock is gone from ->s_instances. Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: pull cifs_mount() call upAl Viro2011-06-251-12/+15
| | | | | | | | | ... to the point prior to sget(). Now we have cifs_sb set up early enough. Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* sanitize cifs_umount() prototypeAl Viro2011-06-251-4/+2
| | | | | | | | | a) superblock argument is unused b) it always returns 0 Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: initialize ->tlink_tree in cifs_setup_cifs_sb()Al Viro2011-06-251-3/+0
| | | | | | | | | no need to wait until cifs_read_super() and we need it done by the time cifs_mount() will be called. Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: allocate mountdata earlierAl Viro2011-06-251-11/+10
| | | | | | | | | pull mountdata allocation up, so that it won't stand in the way when we lift cifs_mount() to location before sget(). Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: leak on mount if we share superblockAl Viro2011-06-251-0/+2
| | | | | | | | cifs_sb and nls end up leaked... Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: don't pass superblock to cifs_mount()Al Viro2011-06-251-1/+12
| | | | | | | | | | | | | | To close sget() races we'll need to be able to set cifs_sb up before we get the superblock, so we'll want to be able to do cifs_mount() earlier. Fortunately, it's easy to do - setting ->s_maxbytes can be done in cifs_read_super(), ditto for ->s_time_gran and as for putting MS_POSIXACL into ->s_flags, we can mirror it in ->mnt_cifs_flags until cifs_read_super() is called. Kill unused 'devname' argument, while we are at it... Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: don't leak nls on mount failureAl Viro2011-06-251-0/+1
| | | | | | | | | | if cifs_sb allocation fails, we still need to drop nls we'd stashed into volume_info - the one we would've copied to cifs_sb if we could allocate the latter. Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: double free on mount failureAl Viro2011-06-251-6/+8
| | | | | | | | | | | | | | | | | | if we get to out_super with ->s_root already set (e.g. with cifs_get_root() failure), we'll end up with cifs_put_super() called and ->mountdata freed twice. We'll also get cifs_sb freed twice and cifs_sb->local_nls dropped twice. The problem is, we can get to out_super both with and without ->s_root, which makes ->put_super() a bad place for such work. Switch to ->kill_sb(), have all that work done there after kill_anon_super(). Unlike ->put_super(), ->kill_sb() is called by deactivate_locked_super() whether we have ->s_root or not. Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* take bdi setup/destruction into cifs_mount/cifs_umountAl Viro2011-06-251-11/+1
| | | | | | Acked-by: Pavel Shilovsky <piastryyy@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs_permission() doesn't need to bail out in RCU modeAl Viro2011-06-201-3/+0
| | | | | | | nothing potentially blocking except generic_permission(), which will DTRT Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* cifs: show sec= option in /proc/mountsJeff Layton2011-06-131-0/+33
| | | | | Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* [CIFS] Rename three structures to avoid camel caseSteve French2011-05-271-3/+3
| | | | | | | | | | secMode to sec_mode and cifsTconInfo to cifs_tcon and cifsSesInfo to cifs_ses Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: Add rwpidforward mount optionPavel Shilovsky2011-05-271-0/+8
| | | | | | | | | | | | | | | | | | Add rwpidforward mount option that switches on a mode when we forward pid of a process who opened a file to any read and write operation. This can prevent applications like WINE from failing on read or write operation on a previously locked file region from the same netfd from another process if we use mandatory brlock style. It is actual for WINE because during a run of WINE program two processes work on the same netfd - share the same file struct between several VFS fds: 1) WINE-server does open and lock; 2) WINE-application does read and write. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: Migrate to shared superblock modelPavel Shilovsky2011-05-271-1/+18
| | | | | | | | | | Add cifs_match_super to use in sget to share superblock between mounts that have the same //server/sharename, credentials and mount options. It helps us to improve performance on work with future SMB2.1 leases. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* [CIFS] Migrate from prefixpath logicSteve French2011-05-271-3/+98
| | | | | | | | | | | Now we point superblock to a server share root and set a root dentry appropriately. This let us share superblock between mounts like //server/sharename/foo/bar and //server/sharename/foo further. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: Fix memory leak in cifs_do_mountPavel Shilovsky2011-05-271-9/+10
| | | | | | | and simplify error handling code. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: Fix undefined behavior when mount failsPavel Shilovsky2011-05-251-27/+17
| | | | | | | | Fix double kfree() calls on the same pointers and cleanup mount code. Reviewed-and-Tested-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: Simplify mount code for further shared sb capabilityPavel Shilovsky2011-05-241-31/+57
| | | | | | | | Reorganize code to get mount option at first and when get a superblock. This lets us use shared superblock model further for equal mounts. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* [CIFS] Fix to problem with getattr caused by invalidate simplification patchSteve French2011-05-201-2/+4
| | | | | | | | | Fix to earlier "Simplify invalidate part (try #6)" patch That patch caused problems with connectathon test 5. Reviewed-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: Change key name to cifs.idmap, misc. clean-upShirish Pargaonkar2011-05-191-3/+5
| | | | | | | | | | Change idmap key name from cifs.cifs_idmap to cifs.idmap. Removed unused structure wksidarr and function match_sid(). Handle errors correctly in function init_cifs(). Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: Unconditionally copy mount options to superblock infoSean Finney2011-05-191-7/+1
| | | | | | | | | | | Previously mount options were copied and updated in the cifs_sb_info struct only when CONFIG_CIFS_DFS_UPCALL was enabled. Making this information generally available allows us to remove a number of ifdefs, extra function params, and temporary variables. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Sean Finney <seanius@seanius.net> Signed-off-by: Steve French <sfrench@us.ibm.com>
* cifs: Use kstrndup for cifs_sb->mountdataSean Finney2011-05-191-11/+6
| | | | | | | | | | | A relatively minor nit, but also clarified the "consensus" from the preceding comments that it is in fact better to try for the kstrdup early and cleanup while cleaning up is still a simple thing to do. Reviewed-By: Steve French <smfrench@gmail.com> Signed-off-by: Sean Finney <seanius@seanius.net> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: Simplify invalidate part (try #5)Pavel Shilovsky2011-05-191-10/+23
| | | | | | | | | Simplify many places when we call cifs_revalidate/invalidate to make it do what it exactly needs. Reviewed-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <sfrench@us.ibm.com>
* CIFS: directio read/write cleanupsPavel Shilovsky2011-05-191-8/+10
| | | | | | | | | | Recently introduced strictcache mode brought a new code that can be efficiently used by directio part. That's let us add vectored operations and break unnecessary cifs_user_read and cifs_user_write. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>