Merge 3.2 to HEAD:

15128: Merge 3.1 to 3.2:
   		15114: Added support for impersonation level sharing mode check, to fix Office2007 file open issue. ETHREEOH-2320.
	15130: Record-only
	15340: Merge 3.1 to 3.2:
   		14359: Fixed native call being used when <disableNative/> was configured. ETHREEOH-2105. (Record-only)
   		14484: Merged HEAD to v3.1: (Record-only)
       	13943 Added FTP IPv6 configuration, via the <IPv6 state="enabled|disabled"/> tag. Added the ftp.ipv6 property. MOB-714.
   		14523: Add trailing 'A' to CIFS server name, removed by recent checkin. (Record-only)
   		14561: Change the file server config bean to use the 'org.alfresco.fileserver' logging level.
   		14916: Fixes for local domain lookup when WINS is configured. ETHREEOH-2263.
   		14922: Merge HEAD to V3.1
       	14626: Fixes for the client side Windows desktop action application. part of ETHREEOH-401
   		15155: Fixes to client side desktop action exe handling of paths that are not mapped to the root of the Alfresco share. ETHREEOH-1613
	15341: Record-only
	15549: Check for null ClientInfo in the setCurrentUser() method and clear the auth context. Part of ETHREEOH-2538.
	15550: Fixed performance issue in the continue search code, add warn level output of folder search timing.
	15564: Merge 3.1 to 3.2:
   		14964: Port fix for convert content I/O exceptions to file server exceptions during write and truncate (part 2). ETWOTWO-1241
   		15233: Ignore nodes that no longer exist during the second stage of a file server folder search.
   		15234: Fixed incorrect length check when buffering MSOffice document writes.
	15565: Record-only
	15568: Fix for cut/paste file between folders on CIFS. ETHREEOH-2323 + ENH-515.
	15569: Record-only
	15644: Changed filesystem debug setting so it works with old and new config styles.
	15786: Record-only
	15787: Port of repo filesystem MS Office document locking fix. ETHREEOH-2579


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16122 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gary Spencer
2009-09-07 13:04:53 +00:00
parent a4445319d8
commit a6eb590cc9
13 changed files with 585 additions and 262 deletions

Binary file not shown.

View File

@@ -321,7 +321,7 @@ bool CAlfrescoApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringLi
// Convert the path to a UNC path // Convert the path to a UNC path
String uncPath = alfresco.getRootPath(); String uncPath = alfresco.getRootPath();
uncPath.append( curFile.substring(2)); uncPath.append( curFile.substring(3));
curFile = uncPath; curFile = uncPath;
} }
@@ -356,7 +356,8 @@ bool CAlfrescoApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringLi
// If the path is to a file that is not on the Alfresco share the file will need to be copied, // If the path is to a file that is not on the Alfresco share the file will need to be copied,
// after checking the status of a matching file in the Alfresco folder // after checking the status of a matching file in the Alfresco folder
if ( curFile.length() >= 3 && curFile.substring(1,3).equals( L":\\")) { if ( curFile.length() >= 3 && curFile.startsWithIgnoreCase( alfresco.getDrivePath()) == false &&
curFile.substring(1,3).equals( L":\\")) {
// Check if the action supports local files // Check if the action supports local files

View File

@@ -53,8 +53,8 @@ namespace Alfresco {
#define FSCTL_ALFRESCO_FILESTS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_ALFRESCO_FILESTS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Version 1 FSCTL_ALFRESCO_CHECKOUT - 0x802 // Version 1 FSCTL_ALFRESCO_CHECKOUT - 0x802
// Version 1 FSCTL_ALFRESCO_CHECKIN - 0x803 // Version 1 FSCTL_ALFRESCO_CHECKIN - 0x803
#define FSCTL_ALFRESCO_GETACTIONINFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x804, METHOD_BUFFERED, FILE_WRITE_DATA) #define FSCTL_ALFRESCO_GETACTIONINFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_ALFRESCO_RUNACTION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x805, METHOD_BUFFERED, FILE_WRITE_DATA) #define FSCTL_ALFRESCO_RUNACTION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_ALFRESCO_GETAUTHTICKET CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_ALFRESCO_GETAUTHTICKET CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Request signature bytes // Request signature bytes

View File

@@ -330,12 +330,16 @@ bool AlfrescoInterface::setRootPath( const wchar_t* rootPath) {
if ( m_handle != INVALID_HANDLE_VALUE) if ( m_handle != INVALID_HANDLE_VALUE)
CloseHandle(m_handle); CloseHandle(m_handle);
// Clear the root path
m_rootPath = "";
// Check if the path is to a mapped drive // Check if the path is to a mapped drive
String path = rootPath; String path = rootPath;
String alfPath = rootPath; String alfPath = rootPath;
if ( alfPath.length() >= 3 && alfPath.substring(1,3).equals( L":\\")) { if ( alfPath.length() >= 2 && alfPath.charAt(1) == ':') {
// Try and convert the local path to a UNC path // Try and convert the local path to a UNC path
@@ -353,6 +357,10 @@ bool AlfrescoInterface::setRootPath( const wchar_t* rootPath) {
if ( alfPath.endsWith( PathSeperator) == false) if ( alfPath.endsWith( PathSeperator) == false)
alfPath.append( PathSeperator); alfPath.append( PathSeperator);
m_rootPath = alfPath;
// Build the full UNC path to the target
if ( path.length() > 3) if ( path.length() > 3)
alfPath.append( path.substring( 3)); alfPath.append( path.substring( 3));
} }
@@ -395,13 +403,15 @@ bool AlfrescoInterface::setRootPath( const wchar_t* rootPath) {
// Set the root path // Set the root path
int pos = m_uncPath.indexOf( PathSeperator, 2); if ( m_rootPath.length() == 0) {
if ( pos != -1) { int pos = m_uncPath.indexOf( PathSeperator, 2);
pos = m_uncPath.indexOf( PathSeperator, pos + 1); if ( pos != -1) {
if ( pos == -1) pos = m_uncPath.indexOf( PathSeperator, pos + 1);
m_rootPath = m_uncPath; if ( pos == -1)
else m_rootPath = m_uncPath;
m_rootPath = m_uncPath.substring(0, pos); else
m_rootPath = m_uncPath.substring(0, pos);
}
} }
} }

View File

@@ -34,8 +34,6 @@ import java.util.Enumeration;
import java.util.Locale; import java.util.Locale;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import net.sf.acegisecurity.AuthenticationManager;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoClientInfoFactory; import org.alfresco.filesys.alfresco.AlfrescoClientInfoFactory;
import org.alfresco.filesys.alfresco.ExtendedDiskInterface; import org.alfresco.filesys.alfresco.ExtendedDiskInterface;
@@ -430,6 +428,23 @@ public abstract class AbstractServerConfigurationBean extends ServerConfiguratio
ClientInfo.setFactory( new AlfrescoClientInfoFactory()); ClientInfo.setFactory( new AlfrescoClientInfoFactory());
// We need to check for a WINS server configuration in the CIFS server config section to initialize
// the NetBIOS name lookups to use WINS rather broadcast lookups, which may be used to get the local
// domain
try {
// Get the CIFS server config section and extract the WINS server config, if available
processWINSServerConfig();
}
catch (Exception ex) {
// Configuration error
logger.error("File server configuration error (WINS), " + ex.getMessage(), ex);
}
// Initialize the filesystems // Initialize the filesystems
try try
@@ -531,6 +546,8 @@ public abstract class AbstractServerConfigurationBean extends ServerConfiguratio
protected abstract void processNFSServerConfig(); protected abstract void processNFSServerConfig();
protected abstract void processFTPServerConfig(); protected abstract void processFTPServerConfig();
protected void processWINSServerConfig() {}
/** /**
* Close the configuration bean * Close the configuration bean

View File

@@ -1880,6 +1880,20 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean {
boolean changeNotify = elem.getChild("disableChangeNotification") == null ? true : false; boolean changeNotify = elem.getChild("disableChangeNotification") == null ? true : false;
// Check if filesyststem debug flags are enabled
ConfigElement filesysDbgElem = elem.getChild("debug");
if (filesysDbgElem != null)
{
// Check for filesystem debug flags
String flags = filesysDbgElem.getAttribute("flags");
// Set the filesystem debug flags
filesysContext.setDebug( flags);
}
// Create the shared filesystem // Create the shared filesystem
filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext); filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext);
@@ -2624,4 +2638,51 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean {
return desktopActions; return desktopActions;
} }
/**
* Parse the CIFS server config section to get the WINS server details, if available
*
* @param config Config
*/
protected void processWINSServerConfig( Config config)
{
// Check if WINS servers are configured
ConfigElement elem = config.getConfigElement("WINS");
if (elem != null)
{
// Get the primary WINS server
ConfigElement priWinsElem = elem.getChild("primary");
if (priWinsElem == null || priWinsElem.getValue().length() == 0)
throw new AlfrescoRuntimeException("No primary WINS server configured");
// Validate the WINS server address
InetAddress primaryWINS = null;
try
{
primaryWINS = InetAddress.getByName(priWinsElem.getValue());
}
catch (UnknownHostException ex)
{
throw new AlfrescoRuntimeException("Invalid primary WINS server address, " + priWinsElem.getValue());
}
// Pass the setting to the NetBIOS session class
NetBIOSSession.setDefaultWINSServer(primaryWINS);
}
}
/**
* Parse the CIFS server config section to get the WINS server details, if available
*/
protected void processWINSServerConfig()
{
processWINSServerConfig(m_configService.getConfig(ConfigCIFS, configCtx));
}
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.filesys.alfresco;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.config.GlobalDesktopActionConfigBean; import org.alfresco.filesys.config.GlobalDesktopActionConfigBean;
@@ -52,6 +53,20 @@ public abstract class AlfrescoContext extends DiskDeviceContext
private static final String TokenLocalName = "${localname}"; private static final String TokenLocalName = "${localname}";
// Debug levels
public final static int DBG_FILE = 0x00000001; // file/folder create/delete
public final static int DBG_FILEIO = 0x00000002; // file read/write/truncate
public final static int DBG_SEARCH = 0x00000004; // folder search
public final static int DBG_INFO = 0x00000008; // file/folder information
public final static int DBG_LOCK = 0x00000010; // file byte range locking
public final static int DBG_PSEUDO = 0x00000020; // pseudo files/folders
public final static int DBG_RENAME = 0x00000040; // rename file/folder
// Filesystem debug flag strings
private static final String m_filesysDebugStr[] = { "FILE", "FILEIO", "SEARCH", "INFO", "LOCK", "PSEUDO", "RENAME" };
// File state table and associated file state reaper // File state table and associated file state reaper
private FileStateTable m_stateTable; private FileStateTable m_stateTable;
@@ -76,6 +91,12 @@ public abstract class AlfrescoContext extends DiskDeviceContext
private IOControlHandler m_ioHandler; private IOControlHandler m_ioHandler;
// Debug flags
//
// Requires the logger to be enabled for debug output
public int m_debug;
public AlfrescoContext() public AlfrescoContext()
{ {
// Default the filesystem to look like an 80Gb sized disk with 90% free space // Default the filesystem to look like an 80Gb sized disk with 90% free space
@@ -456,6 +477,65 @@ public abstract class AlfrescoContext extends DiskDeviceContext
m_ioHandler = ioctlHandler; m_ioHandler = ioctlHandler;
} }
/**
* Set the debug flags, also requires the logger to be enabled for debug output
*
* @param dbg int
*/
public final void setDebug(String flagsStr)
{
int filesysDbg = 0;
if (flagsStr != null)
{
// Parse the flags
StringTokenizer token = new StringTokenizer(flagsStr.toUpperCase(), ",");
while (token.hasMoreTokens())
{
// Get the current debug flag token
String dbg = token.nextToken().trim();
// Find the debug flag name
int idx = 0;
boolean match = false;
while (idx < m_filesysDebugStr.length && match == false)
{
if ( m_filesysDebugStr[idx].equalsIgnoreCase(dbg) == true)
match = true;
else
idx++;
}
if (match == false)
throw new AlfrescoRuntimeException("Invalid filesystem debug flag, " + dbg);
// Set the debug flag
filesysDbg += 1 << idx;
}
// Set the debug flags
m_debug = filesysDbg;
}
}
/**
* Check if a debug flag is enabled
*
* @param flg int
* @return boolean
*/
public final boolean hasDebug(int flg)
{
return (m_debug & flg) != 0 ? true : false;
}
/** /**
* Close the filesystem context * Close the filesystem context
*/ */

View File

@@ -413,7 +413,7 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator implements
// Check the account type and setup the authentication context // Check the account type and setup the authentication context
if (client.isNullSession()) if (client == null || client.isNullSession())
{ {
// Clear the authentication, null user should not be allowed to do any service calls // Clear the authentication, null user should not be allowed to do any service calls

View File

@@ -34,6 +34,7 @@ import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoContext;
import org.alfresco.filesys.alfresco.AlfrescoDiskDriver; import org.alfresco.filesys.alfresco.AlfrescoDiskDriver;
import org.alfresco.filesys.alfresco.AlfrescoNetworkFile; import org.alfresco.filesys.alfresco.AlfrescoNetworkFile;
import org.alfresco.filesys.state.FileState; import org.alfresco.filesys.state.FileState;
@@ -64,6 +65,7 @@ import org.alfresco.jlan.server.filesys.pseudo.PseudoNetworkFile;
import org.alfresco.jlan.server.locking.FileLockingInterface; import org.alfresco.jlan.server.locking.FileLockingInterface;
import org.alfresco.jlan.server.locking.LockManager; import org.alfresco.jlan.server.locking.LockManager;
import org.alfresco.jlan.smb.SharingMode; import org.alfresco.jlan.smb.SharingMode;
import org.alfresco.jlan.smb.WinNT;
import org.alfresco.jlan.smb.server.SMBServer; import org.alfresco.jlan.smb.server.SMBServer;
import org.alfresco.jlan.smb.server.SMBSrvSession; import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.jlan.util.WildCard; import org.alfresco.jlan.util.WildCard;
@@ -701,7 +703,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug( "Added file state for pseudo files folder (getinfo) - " + paths[0]); logger.debug( "Added file state for pseudo files folder (getinfo) - " + paths[0]);
} }
else if ( fstate.hasPseudoFiles() == false) else if ( fstate.hasPseudoFiles() == false)
@@ -721,7 +723,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug( "Added pseudo files for folder (exists) - " + paths[0]); logger.debug( "Added pseudo files for folder (exists) - " + paths[0]);
} }
@@ -732,7 +734,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
if ( pfile != null) if ( pfile != null)
{ {
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("getInfo using pseudo file info for " + path); logger.debug("getInfo using pseudo file info for " + path);
FileInfo pseudoFileInfo = pfile.getFileInfo(); FileInfo pseudoFileInfo = pfile.getFileInfo();
@@ -761,7 +763,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("getInfo using cached noderef for path " + path); logger.debug("getInfo using cached noderef for path " + path);
} }
@@ -785,7 +787,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("getInfo using cached noderef for parent " + path); logger.debug("getInfo using cached noderef for parent " + path);
} }
} }
@@ -796,12 +798,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
{ logger.debug("Getting file information: path=" + path + " file info: " + finfo);
logger.debug("Getting file information: \n" +
" path: " + path + "\n" +
" file info: " + finfo);
}
} }
// Set the file id for the file using the relative path // Set the file id for the file using the relative path
@@ -833,16 +831,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Getting file information - File not found: \n" + logger.debug("Get file info - file not found, " + path);
" path: " + path);
throw e; throw e;
} }
catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) catch (org.alfresco.repo.security.permissions.AccessDeniedException ex)
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Get file info - access denied, " + path); logger.debug("Get file info - access denied, " + path);
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -853,7 +850,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Get file info error", ex); logger.debug("Get file info error", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -875,12 +872,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
*/ */
public SearchContext startSearch(SrvSession sess, TreeConnection tree, String searchPath, int attributes) throws FileNotFoundException public SearchContext startSearch(SrvSession sess, TreeConnection tree, String searchPath, int attributes) throws FileNotFoundException
{ {
// Access the device context
ContentContext ctx = (ContentContext) tree.getContext();
try try
{ {
// Access the device context
ContentContext ctx = (ContentContext) tree.getContext();
String searchFileSpec = searchPath; String searchFileSpec = searchPath;
NodeRef searchRootNodeRef = ctx.getRootNode(); NodeRef searchRootNodeRef = ctx.getRootNode();
FileState searchFolderState = null; FileState searchFolderState = null;
@@ -937,7 +934,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Search using cached noderef for path " + searchPath); logger.debug("Search using cached noderef for path " + searchPath);
} }
} }
@@ -948,10 +945,25 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
if ( searchFileSpec.equals( "*.*")) if ( searchFileSpec.equals( "*.*"))
searchFileSpec = "*"; searchFileSpec = "*";
// Debug
long startTime = 0L;
if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
startTime = System.currentTimeMillis();
// Perform the search // Perform the search
List<NodeRef> results = cifsHelper.getNodeRefs(searchRootNodeRef, searchFileSpec); List<NodeRef> results = cifsHelper.getNodeRefs(searchRootNodeRef, searchFileSpec);
// Debug
if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH)) {
long endTime = System.currentTimeMillis();
if (( endTime - startTime) > 500)
logger.debug("Search for searchPath=" + searchPath + ", searchSpec=" + searchFileSpec + ", searchRootNode=" + searchRootNodeRef + " took "
+ ( endTime - startTime) + "ms results=" + results.size());
}
// Check if there are any pseudo files for the folder being searched, for CIFS only // Check if there are any pseudo files for the folder being searched, for CIFS only
PseudoFileList pseudoList = null; PseudoFileList pseudoList = null;
@@ -1021,19 +1033,16 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
{ logger.debug("Started search: search path=" + searchPath + " attributes=" + attributes);
logger.debug("Started search: \n" +
" search path: " + searchPath + "\n" +
" attributes: " + attributes);
}
return searchCtx; return searchCtx;
} }
catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) catch (org.alfresco.repo.security.permissions.AccessDeniedException ex)
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Start search - access denied, " + searchPath); logger.debug("Start search - access denied, " + searchPath);
// Convert to a file not found status // Convert to a file not found status
@@ -1044,7 +1053,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_SEARCH))
logger.debug("Start search", ex); logger.debug("Start search", ex);
// Convert to a file not found status // Convert to a file not found status
@@ -1064,14 +1073,13 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
*/ */
public int fileExists(SrvSession sess, TreeConnection tree, String name) public int fileExists(SrvSession sess, TreeConnection tree, String name)
{ {
ContentContext ctx = (ContentContext) tree.getContext();
int status = FileStatus.Unknown; int status = FileStatus.Unknown;
try try
{ {
// Check for a cached file state // Check for a cached file state
ContentContext ctx = (ContentContext) tree.getContext();
FileState fstate = null; FileState fstate = null;
if ( ctx.hasStateTable()) if ( ctx.hasStateTable())
@@ -1090,7 +1098,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Cache hit - fileExists() " + name + ", sts=" + status); logger.debug("Cache hit - fileExists() " + name + ", sts=" + status);
} }
else else
@@ -1131,7 +1139,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_PSEUDO))
logger.debug( "Added file state for pseudo files folder (exists) - " + paths[0]); logger.debug( "Added file state for pseudo files folder (exists) - " + paths[0]);
} }
} }
@@ -1156,7 +1164,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_PSEUDO))
logger.debug( "Added pseudo files for folder (exists) - " + paths[0]); logger.debug( "Added pseudo files for folder (exists) - " + paths[0]);
} }
@@ -1173,7 +1181,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Failed to find pseudo file // Failed to find pseudo file
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_PSEUDO))
logger.debug( "Failed to find pseudo file (exists) - " + name); logger.debug( "Failed to find pseudo file (exists) - " + name);
} }
} }
@@ -1208,20 +1216,17 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
catch (IOException e) catch (IOException e)
{ {
// Debug // Debug
logger.debug("File exists error, " + name, e); if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("File exists error, " + name, e);
status = FileStatus.NotExist; status = FileStatus.NotExist;
} }
// Debug // Debug
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
{ logger.debug("File status determined: name=" + name + " status=" + FileStatus.asString(status));
logger.debug("File status determined: \n" +
" name: " + name + "\n" +
" status: " + status);
}
// Return the file/folder status // Return the file/folder status
@@ -1242,13 +1247,10 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Create the transaction // Create the transaction
beginReadTransaction( sess); beginReadTransaction( sess);
ContentContext ctx = (ContentContext) tree.getContext();
try try
{ {
// Get the node for the path
ContentContext ctx = (ContentContext) tree.getContext();
// Check if pseudo files are enabled // Check if pseudo files are enabled
if ( hasPseudoFileInterface(ctx)) if ( hasPseudoFileInterface(ctx))
@@ -1279,7 +1281,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_PSEUDO))
logger.debug( "Added file state for pseudo files folder (open) - " + paths[0]); logger.debug( "Added file state for pseudo files folder (open) - " + paths[0]);
} }
} }
@@ -1291,7 +1293,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_PSEUDO))
logger.debug( "Added pseudo files for folder (open) - " + paths[0]); logger.debug( "Added pseudo files for folder (open) - " + paths[0]);
} }
@@ -1308,7 +1310,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Failed to find pseudo file // Failed to find pseudo file
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_PSEUDO))
logger.debug( "Failed to find pseudo file (open) - " + params.getPath()); logger.debug( "Failed to find pseudo file (open) - " + params.getPath());
} }
} }
@@ -1361,46 +1363,102 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
if ( fstate.exists() == false) if ( fstate.exists() == false)
throw new FileNotFoundException(); throw new FileNotFoundException();
// Check the file sharing mode
if ( fstate != null) {
// Check if the current file open allows the required shared access
boolean nosharing = false;
if ( fstate.getOpenCount() > 0) {
// Check if the file has been opened for exclusive access
if ( fstate.getSharedAccess() == SharingMode.NOSHARING)
nosharing = true;
// Check if the required sharing mode is allowed by the current file open
else if ( ( fstate.getSharedAccess() & params.getSharedAccess()) != params.getSharedAccess())
nosharing = true;
// Check if the caller wants exclusive access to the file
else if ( params.getSharedAccess() == SharingMode.NOSHARING)
nosharing = true;
}
// Check if the file allows shared access
if ( nosharing == true)
{
if ( params.getPath().equals( "\\") == false)
throw new FileSharingException("File already open, " + params.getPath());
}
// Update the file sharing mode, if this is the first file open
fstate.setSharedAccess( params.getSharedAccess());
}
} }
else {
// Create a file state for the path
fstate = ctx.getStateTable().findFileState( params.getPath(), false, true);
}
// Check if the current file open allows the required shared access
boolean nosharing = false;
// TEST
if ( params.getAccessMode() == AccessMode.NTFileGenericExecute && params.getPath().toLowerCase().endsWith( ".exe") == false) {
// DEBUG
if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE)) {
logger.debug( "Execute access mode, path" + params.getPath());
logger.debug( " Fstate=" + fstate);
}
throw new AccessDeniedException("Invalid access mode");
}
if ( fstate.getOpenCount() > 0) {
// Check for impersonation security level from the original process that opened the file
if ( params.getSecurityLevel() == WinNT.SecurityImpersonation && params.getProcessId() == fstate.getProcessId())
nosharing = false;
// Check if the caller wants read access, check the sharing mode
// Check if the caller wants write access, check if the sharing mode allows write
else if ( params.isReadOnlyAccess() && (fstate.getSharedAccess() & SharingMode.READ) != 0)
nosharing = false;
// Check if the caller wants write access, check the sharing mode
else if (( params.isReadWriteAccess() || params.isWriteOnlyAccess()) && (fstate.getSharedAccess() & SharingMode.WRITE) == 0)
{
// DEBUG
if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Sharing mode disallows write access path=" + params.getPath());
// Access not allowed
throw new AccessDeniedException( "Sharing mode (write)");
}
// Check if the file has been opened for exclusive access
else if ( fstate.getSharedAccess() == SharingMode.NOSHARING)
nosharing = true;
// Check if the required sharing mode is allowed by the current file open
else if ( ( fstate.getSharedAccess() & params.getSharedAccess()) != params.getSharedAccess())
nosharing = true;
// Check if the caller wants exclusive access to the file
else if ( params.getSharedAccess() == SharingMode.NOSHARING)
nosharing = true;
}
// Check if the file allows shared access
if ( nosharing == true)
{
if ( params.getPath().equals( "\\") == false) {
// DEBUG
if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Sharing violation path=" + params.getPath() + ", sharing=0x" + Integer.toHexString(fstate.getSharedAccess()));
// File is locked by another user
throw new FileSharingException("File already open, " + params.getPath());
}
}
// Update the file sharing mode and process id, if this is the first file open
fstate.setSharedAccess( params.getSharedAccess());
fstate.setProcessId( params.getProcessId());
// DEBUG
if ( logger.isDebugEnabled() && fstate.getOpenCount() == 0 && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Path " + params.getPath() + ", sharing=0x" + Integer.toHexString(params.getSharedAccess()) + ", PID=" + params.getProcessId());
} }
// Check if the node is a link node // Check if the node is a link node
@@ -1508,13 +1566,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Debug // Debug
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
{ logger.debug("Opened network file: path=" + params.getPath() + " file open parameters=" + params + " network file=" + netFile);
logger.debug("Opened network file: \n" +
" path: " + params.getPath() + "\n" +
" file open parameters: " + params + "\n" +
" network file: " + netFile);
}
// Return the network file // Return the network file
@@ -1524,7 +1577,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Open file - access denied, " + params.getFullPath()); logger.debug("Open file - access denied, " + params.getFullPath());
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -1535,7 +1588,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Open file error", ex); logger.debug("Open file error", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -1558,14 +1611,13 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Create the transaction // Create the transaction
beginWriteTransaction( sess); beginWriteTransaction( sess);
ContentContext ctx = (ContentContext) tree.getContext();
try try
{ {
// Get the device root // Get the device root
ContentContext ctx = (ContentContext) tree.getContext();
NodeRef deviceRootNodeRef = ctx.getRootNode(); NodeRef deviceRootNodeRef = ctx.getRootNode();
String path = params.getPath(); String path = params.getPath();
// If the state table is available then try to find the parent folder node for the new file // If the state table is available then try to find the parent folder node for the new file
@@ -1589,7 +1641,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create file using cached noderef for path " + paths[0]); logger.debug("Create file using cached noderef for path " + paths[0]);
} }
} }
@@ -1626,6 +1678,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Save the file sharing mode, needs to be done before the open count is incremented // Save the file sharing mode, needs to be done before the open count is incremented
fstate.setSharedAccess( params.getSharedAccess()); fstate.setSharedAccess( params.getSharedAccess());
fstate.setProcessId( params.getProcessId());
// Indicate that the file is open // Indicate that the file is open
@@ -1639,20 +1692,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create file, state=" + fstate); logger.debug("Create file, state=" + fstate);
} }
} }
// done // Debug
if (logger.isDebugEnabled())
{ if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Created file: \n" + logger.debug("Created file: path=" + path + " file open parameters=" + params + " node=" + nodeRef + " network file=" + netFile);
" path: " + path + "\n" +
" file open parameters: " + params + "\n" +
" node: " + nodeRef + "\n" +
" network file: " + netFile);
}
return netFile; return netFile;
} }
@@ -1660,7 +1708,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create file - access denied, " + params.getFullPath()); logger.debug("Create file - access denied, " + params.getFullPath());
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -1671,7 +1719,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create file - content I/O error, " + params.getFullPath()); logger.debug("Create file - content I/O error, " + params.getFullPath());
// Convert to a filesystem disk full status // Convert to a filesystem disk full status
@@ -1682,7 +1730,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create file error", ex); logger.debug("Create file error", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -1705,12 +1753,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Create the transaction // Create the transaction
beginWriteTransaction( sess); beginWriteTransaction( sess);
ContentContext ctx = (ContentContext) tree.getContext();
try try
{ {
// get the device root // get the device root
ContentContext ctx = (ContentContext) tree.getContext();
NodeRef deviceRootNodeRef = ctx.getRootNode(); NodeRef deviceRootNodeRef = ctx.getRootNode();
String path = params.getPath(); String path = params.getPath();
@@ -1736,7 +1784,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create file using cached noderef for path " + paths[0]); logger.debug("Create file using cached noderef for path " + paths[0]);
} }
} }
@@ -1760,25 +1808,21 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Creaste folder, state=" + fstate); logger.debug("Creaste folder, state=" + fstate);
} }
} }
// done // Debug
if (logger.isDebugEnabled())
{ if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Created directory: \n" + logger.debug("Created directory: path=" + path + " file open params=" + params + " node=" + nodeRef);
" path: " + path + "\n" +
" file open params: " + params + "\n" +
" node: " + nodeRef);
}
} }
catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) catch (org.alfresco.repo.security.permissions.AccessDeniedException ex)
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create directory - access denied, " + params.getFullPath()); logger.debug("Create directory - access denied, " + params.getFullPath());
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -1789,7 +1833,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Create directory error", ex); logger.debug("Create directory error", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -1841,28 +1885,23 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
throw new DirectoryNotEmptyException( dir); throw new DirectoryNotEmptyException( dir);
} }
// done // Debug
if (logger.isDebugEnabled())
{ if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Deleted directory: \n" + logger.debug("Deleted directory: directory=" + dir + " node=" + nodeRef);
" directory: " + dir + "\n" +
" node: " + nodeRef);
}
} }
catch (FileNotFoundException e) catch (FileNotFoundException e)
{ {
// already gone // Debug
if (logger.isDebugEnabled())
{ if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Deleted directory <alfready gone>: \n" + logger.debug("Delete directory - file not found, " + dir);
" directory: " + dir);
}
} }
catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) catch (org.alfresco.repo.security.permissions.AccessDeniedException ex)
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete directory - access denied, " + dir); logger.debug("Delete directory - access denied, " + dir);
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -1873,7 +1912,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete directory", ex); logger.debug("Delete directory", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -1892,6 +1931,13 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
*/ */
public void flushFile(SrvSession sess, TreeConnection tree, NetworkFile file) throws IOException public void flushFile(SrvSession sess, TreeConnection tree, NetworkFile file) throws IOException
{ {
// Debug
ContentContext ctx = (ContentContext) tree.getContext();
if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILEIO))
logger.debug("Flush file=" + file.getFullName());
// Flush the file data // Flush the file data
file.flushFile(); file.flushFile();
@@ -1956,7 +2002,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
} }
catch ( Exception ex) catch ( Exception ex)
{ {
if ( logger.isWarnEnabled()) if ( logger.isWarnEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.warn("Error during delete on close, " + file.getFullName(), ex); logger.warn("Error during delete on close, " + file.getFullName(), ex);
} }
@@ -1982,7 +2028,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete on close - access denied, " + file.getFullName()); logger.debug("Delete on close - access denied, " + file.getFullName());
// Convert to a filesystem access denied exception // Convert to a filesystem access denied exception
@@ -2007,12 +2053,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
{ logger.debug("Closed file: network file=" + file + " delete on close=" + file.hasDeleteOnClose());
logger.debug("Closed file: \n" +
" network file: " + file + "\n" +
" deleted on close: " + file.hasDeleteOnClose());
}
} }
/** /**
@@ -2048,15 +2090,16 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
ctx.getStateTable().removeFileState(name); ctx.getStateTable().removeFileState(name);
} }
// done // Debug
if (logger.isDebugEnabled())
logger.debug("Deleted file: " + name + ", node: " + nodeRef); if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Deleted file: " + name + ", node=" + nodeRef);
} }
catch (NodeLockedException ex) catch (NodeLockedException ex)
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete file - access denied (locked)"); logger.debug("Delete file - access denied (locked)");
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -2067,7 +2110,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete file - access denied"); logger.debug("Delete file - access denied");
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -2078,7 +2121,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILE))
logger.debug("Delete file error", ex); logger.debug("Delete file error", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -2102,12 +2145,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
beginWriteTransaction( sess); beginWriteTransaction( sess);
// Get the device context
ContentContext ctx = (ContentContext) tree.getContext();
try try
{ {
// Get the device context
ContentContext ctx = (ContentContext) tree.getContext();
// Get the file/folder to move // Get the file/folder to move
NodeRef nodeToMoveRef = getNodeForPath(tree, oldName); NodeRef nodeToMoveRef = getNodeForPath(tree, oldName);
@@ -2156,7 +2199,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Found rename state, relinking, " + renState); logger.debug(" Found rename state, relinking, " + renState);
// Relink the new version of the file data to the previously renamed node so that it // Relink the new version of the file data to the previously renamed node so that it
@@ -2186,7 +2229,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Found delete on close state, restore and relink, " + renState); logger.debug(" Found delete on close state, restore and relink, " + renState);
// Restore the deleted node so we can relink the new version to the old history/properties // Restore the deleted node so we can relink the new version to the old history/properties
@@ -2195,7 +2238,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Found archived node + " + archivedNode); logger.debug(" Found archived node + " + archivedNode);
if ( archivedNode != null && getNodeService().exists( archivedNode)) if ( archivedNode != null && getNodeService().exists( archivedNode))
@@ -2206,7 +2249,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Restored node " + restoredNode); logger.debug(" Restored node " + restoredNode);
if ( restoredNode != null) if ( restoredNode != null)
@@ -2232,7 +2275,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug(" Swapped content to restored node, delete " + oldName + ", nodeRef=" + nodeToMoveRef); logger.debug(" Swapped content to restored node, delete " + oldName + ", nodeRef=" + nodeToMoveRef);
// Link the node ref for the associated rename state // Link the node ref for the associated rename state
@@ -2295,7 +2338,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Added Temporary aspect to renamed file " + newName); logger.debug("Added Temporary aspect to renamed file " + newName);
} }
@@ -2315,14 +2358,14 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Removed Temporary aspect from renamed file " + newName); logger.debug("Removed Temporary aspect from renamed file " + newName);
} }
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Renamed file: from: " + oldName + " to: " + newName); logger.debug("Renamed file: from=" + oldName + " to=" + newName);
} }
else else
{ {
@@ -2332,15 +2375,15 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Moved file: from: " + oldName + " to: " + newName); logger.debug("Moved file: from=" + oldName + " to=" + newName);
} }
// Check if we renamed a file, if so then cache the rename details for a short period // Check if we renamed a file, if so then cache the rename details for a short period
// in case another file renamed to the old name. MS Word uses renames to move a new // in case another file renamed to the old name. MS Word uses renames to move a new
// version of a document into place so we need to reconnect the version history. // version of a document into place so we need to reconnect the version history.
if ( !cifsHelper.isDirectory(nodeToMoveRef)) if ( !cifsHelper.isDirectory(nodeToMoveRef) && sameFolder == true)
{ {
// Get or create a new file state for the old file path // Get or create a new file state for the old file path
@@ -2369,7 +2412,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
{ {
logger.debug("Cached rename state for " + oldName + ", state=" + fstate); logger.debug("Cached rename state for " + oldName + ", state=" + fstate);
logger.debug(" new name " + newName + ", state=" + newState); logger.debug(" new name " + newName + ", state=" + newState);
@@ -2379,14 +2422,14 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if (logger.isDebugEnabled()) if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Moved node: from: " + oldName + " to: " + newName); logger.debug("Moved node: from=" + oldName + " to=" + newName);
} }
catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) catch (org.alfresco.repo.security.permissions.AccessDeniedException ex)
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file - access denied, " + oldName); logger.debug("Rename file - access denied, " + oldName);
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -2397,7 +2440,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file", ex); logger.debug("Rename file", ex);
// Convert to an filesystem access denied exception // Convert to an filesystem access denied exception
@@ -2408,7 +2451,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_RENAME))
logger.debug("Rename file", ex); logger.debug("Rename file", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -2428,12 +2471,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
*/ */
public void setFileInformation(SrvSession sess, TreeConnection tree, String name, FileInfo info) throws IOException public void setFileInformation(SrvSession sess, TreeConnection tree, String name, FileInfo info) throws IOException
{ {
// Get the device context
ContentContext ctx = (ContentContext) tree.getContext();
try try
{ {
// Get the device context
ContentContext ctx = (ContentContext) tree.getContext();
// Check if pseudo files are enabled // Check if pseudo files are enabled
if ( hasPseudoFileInterface(ctx) && if ( hasPseudoFileInterface(ctx) &&
@@ -2496,7 +2539,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set deleteOnClose=true file=" + name); logger.debug("Set deleteOnClose=true file=" + name);
} }
@@ -2520,7 +2563,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set creationDate=" + createDate + " file=" + name); logger.debug("Set creationDate=" + createDate + " file=" + name);
} }
@@ -2544,7 +2587,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set modifyDate=" + modifyDate + " file=" + name); logger.debug("Set modifyDate=" + modifyDate + " file=" + name);
} }
} }
@@ -2552,7 +2595,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Set file information - access denied, " + name); logger.debug("Set file information - access denied, " + name);
// Convert to a filesystem access denied status // Convert to a filesystem access denied status
@@ -2563,7 +2606,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{ {
// Debug // Debug
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_INFO))
logger.debug("Open file error", ex); logger.debug("Open file error", ex);
// Convert to a general I/O exception // Convert to a general I/O exception
@@ -2587,13 +2630,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
file.truncateFile(size); file.truncateFile(size);
// done // Debug
if (logger.isDebugEnabled())
{ ContentContext ctx = (ContentContext) tree.getContext();
logger.debug("Truncated file: \n" +
" network file: " + file + "\n" + if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILEIO))
" size: " + size); logger.debug("Truncated file: network file=" + file + " size=" + size);
}
} }
/** /**
@@ -2639,17 +2681,14 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
count = 0; count = 0;
} }
// done // Debug
if (logger.isDebugEnabled())
{ ContentContext ctx = (ContentContext) tree.getContext();
logger.debug("Read bytes from file: \n" +
" network file: " + file + "\n" + if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILEIO))
" buffer size: " + buffer.length + "\n" + logger.debug("Read bytes from file: network file=" + file + " buffer size=" + buffer.length + " buffer pos=" + bufferPosition +
" buffer pos: " + bufferPosition + "\n" + " size=" + size + " file offset=" + fileOffset + " bytes read=" + count);
" size: " + size + "\n" +
" file offset: " + fileOffset + "\n" +
" bytes read: " + count);
}
return count; return count;
} }
@@ -2712,15 +2751,13 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
file.writeFile(buffer, size, bufferOffset, fileOffset); file.writeFile(buffer, size, bufferOffset, fileOffset);
// done // Debug
if (logger.isDebugEnabled())
{ ContentContext ctx = (ContentContext) tree.getContext();
logger.debug("Wrote bytes to file: \n" +
" network file: " + file + "\n" + if (logger.isDebugEnabled() && ctx.hasDebug(AlfrescoContext.DBG_FILEIO))
" buffer size: " + buffer.length + "\n" + logger.debug("Wrote bytes to file: network file=" + file + " buffer size=" + buffer.length + " size=" + size + " file offset=" + fileOffset);
" size: " + size + "\n" +
" file offset: " + fileOffset);
}
return size; return size;
} }

View File

@@ -47,6 +47,7 @@ import org.alfresco.repo.content.encoding.ContentCharsetFinder;
import org.alfresco.repo.content.filestore.FileContentReader; import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.service.cmr.repository.ContentAccessor; import org.alfresco.service.cmr.repository.ContentAccessor;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
@@ -426,25 +427,38 @@ public class ContentNetworkFile extends NodeRefNetworkFile
public void truncateFile(long size) public void truncateFile(long size)
throws IOException throws IOException
{ {
// If the content data channel has not been opened yet and the requested size is zero try {
// then this is an open for overwrite so the existing content data is not copied // If the content data channel has not been opened yet and the requested size is zero
// then this is an open for overwrite so the existing content data is not copied
if ( hasContent() == false && size == 0L)
{
// Open content for overwrite, no need to copy existing content data
openContent(true, true); if ( hasContent() == false && size == 0L)
} {
else // Open content for overwrite, no need to copy existing content data
{
// Normal open for write openContent(true, true);
}
openContent(true, false); else
{
// Normal open for write
openContent(true, false);
// Truncate or extend the channel // Truncate or extend the channel
channel.truncate(size); channel.truncate(size);
} }
}
catch ( ContentIOException ex) {
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Error opening file " + getFullName() + " for write", ex);
// Convert to a file server I/O error
throw new DiskFullException("Failed to open " + getFullName() + " for write");
}
// Set modification flag // Set modification flag
@@ -477,9 +491,22 @@ public class ContentNetworkFile extends NodeRefNetworkFile
public void writeFile(byte[] buffer, int length, int position, long fileOffset) public void writeFile(byte[] buffer, int length, int position, long fileOffset)
throws IOException throws IOException
{ {
// Open the channel for writing try {
// Open the channel for writing
openContent(true, false);
openContent(true, false);
}
catch ( ContentIOException ex) {
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Error opening file " + getFullName() + " for write", ex);
// Convert to a file server I/O error
throw new DiskFullException("Failed to open " + getFullName() + " for write");
}
// Write to the channel // Write to the channel

View File

@@ -34,6 +34,7 @@ import org.alfresco.jlan.server.filesys.FileType;
import org.alfresco.jlan.server.filesys.SearchContext; import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile; import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList; import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -76,6 +77,10 @@ public class ContentSearchContext extends SearchContext
private String m_relPath; private String m_relPath;
// Keep track of the last file name returned for fast restartAt processing
private String m_lastFileName;
/** /**
* Class constructor * Class constructor
* *
@@ -111,10 +116,18 @@ public class ContentSearchContext extends SearchContext
public String toString() public String toString()
{ {
StringBuilder sb = new StringBuilder(60); StringBuilder sb = new StringBuilder(60);
sb.append("ContentSearchContext")
.append("[ searchStr=").append(getSearchString()) sb.append("[ContentSearchContext searchStr=");
.append(", resultCount=").append(results.size()) sb.append(getSearchString());
.append("]"); sb.append(", resultCount=");
sb.append(results.size());
sb.append(", pseudoList=");
if ( pseudoList != null)
sb.append( pseudoList.numberOfFiles());
else
sb.append("NULL");
sb.append("]");
return sb.toString(); return sb.toString();
} }
@@ -205,17 +218,46 @@ public class ContentSearchContext extends SearchContext
} }
} }
// Get the next file info from the node search // Return the next available file information for a real file/folder
NodeRef nextNodeRef = results.get(index);
try try
{ {
// Get the file information and copy across to the callers file info // Loop until we get a valid node, might have been deleted since the initial folder search
ContentFileInfo nextInfo = cifsHelper.getFileInformation(nextNodeRef, ""); ContentFileInfo nextInfo = null;
info.copyFrom(nextInfo);
while ( nextInfo == null && index < results.size())
{
// Get the next node from the search
NodeRef nextNodeRef = results.get(index);
try {
// Get the file information and copy across to the callers file info
nextInfo = cifsHelper.getFileInformation(nextNodeRef, "");
info.copyFrom(nextInfo);
}
catch ( InvalidNodeRefException ex) {
// Log a warning
if ( logger.isWarnEnabled())
logger.warn("Noderef " + nextNodeRef + " no longer valid, ignoring");
// Update the node index, node no longer exists, try the next node in the search
index++;
resumeId++;
}
}
// Check if we have finished returning file info
if ( nextInfo == null)
return false;
// Generate a file id for the current file // Generate a file id for the current file
StringBuilder pathStr = new StringBuilder( m_relPath); StringBuilder pathStr = new StringBuilder( m_relPath);
@@ -243,6 +285,10 @@ public class ContentSearchContext extends SearchContext
else else
info.setFileType( FileType.RegularFile); info.setFileType( FileType.RegularFile);
// Keep track of the last file name returned
m_lastFileName = info.getFileName();
// Indicate that the file information is valid // Indicate that the file information is valid
return true; return true;
@@ -313,6 +359,10 @@ public class ContentSearchContext extends SearchContext
// Get the file information and copy across to the callers file info // Get the file information and copy across to the callers file info
FileInfo nextInfo = cifsHelper.getFileInformation(nextNodeRef, ""); FileInfo nextInfo = cifsHelper.getFileInformation(nextNodeRef, "");
// Keep track of the last file name returned
m_lastFileName = nextInfo.getFileName();
// Indicate that the file information is valid // Indicate that the file information is valid
@@ -360,6 +410,17 @@ public class ContentSearchContext extends SearchContext
} }
} }
// Check if the resume file name is the last file returned, no need to reposition the file index
if ( m_lastFileName != null && info.getFileName().equalsIgnoreCase( m_lastFileName)) {
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Fast search restart - " + m_lastFileName);
return true;
}
// Check if the resume file is in the main file list // Check if the resume file is in the main file list
if ( results != null) if ( results != null)

View File

@@ -132,7 +132,7 @@ public class MSOfficeContentNetworkFile extends ContentNetworkFile {
// Buffer the write, looks like a file open update. Do not buffer zero length writes. // Buffer the write, looks like a file open update. Do not buffer zero length writes.
if ( length == 0) { if ( length != 0) {
byte[] data = new byte[ length]; byte[] data = new byte[ length];
System.arraycopy(buffer, position, data, 0, length); System.arraycopy(buffer, position, data, 0, length);

View File

@@ -75,9 +75,10 @@ public class FileState
private int m_openCount; private int m_openCount;
// Sharing mode // Sharing mode and PID of first process to open the file
private int m_sharedAccess = SharingMode.READWRITE + SharingMode.DELETE; private int m_sharedAccess = SharingMode.READWRITE + SharingMode.DELETE;
private int m_pid = -1;
// File lock list, allocated once there are active locks on this file // File lock list, allocated once there are active locks on this file
@@ -203,6 +204,16 @@ public class FileState
return m_sharedAccess; return m_sharedAccess;
} }
/**
* Return the PID of the first process to open the file, or -1 if the file is not open
*
* @return int
*/
public final int getProcessId()
{
return m_pid;
}
/** /**
* Check if there are active locks on this file * Check if there are active locks on this file
* *
@@ -279,6 +290,11 @@ public class FileState
else else
m_openCount--; m_openCount--;
// Clear the PID if the file is no longer open
if ( m_openCount == 0)
m_pid = -1;
return m_openCount; return m_openCount;
} }
@@ -430,6 +446,17 @@ public class FileState
m_sharedAccess = mode; m_sharedAccess = mode;
} }
/**
* Set the PID of the process opening the file
*
* @param pid int
*/
public final void setProcessId(int pid)
{
if ( getOpenCount() == 0)
m_pid = pid;
}
/** /**
* Set the file path * Set the file path
* *
@@ -703,6 +730,8 @@ public class FileState
str.append(getFileStatus()); str.append(getFileStatus());
str.append(":Opn="); str.append(":Opn=");
str.append(getOpenCount()); str.append(getOpenCount());
str.append("/");
str.append(getProcessId());
str.append(",Expire="); str.append(",Expire=");
str.append(getSecondsToExpire(System.currentTimeMillis())); str.append(getSecondsToExpire(System.currentTimeMillis()));