Java tutorial
package fuse.okuyamafs; import java.io.*; import java.nio.*; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import fuse.*; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; /** * OkuyamaFuse.<br> * FUSE-J?<br> * * @author T.Okuyama * @license GPL(Lv3) */ public class OkuyamaFilesystem implements Filesystem3, XattrSupport { private static final Log log = LogFactory.getLog(OkuyamaFilesystem.class); public volatile static int blockSizeAssist = 50; public volatile static int blockSize = 1024 * 16 + 5;//5200; // Block //public volatile static int blockSize = 5632; // Block public volatile static int writeBufferSize = 1024 * 1024 * 5 + 1024; public static final int maxSingleModeCacheSize = 200000; public static int storageType = -1; private FuseStatfs statfs; private String masterNodeStr = null; OkuyamaClientWrapper client = null; private Map openStatusMap = new Hashtable(); private Map appendWriteDataBuf = new HashMap(10); private GroupingKeyMap writeBufFpMap = new GroupingKeyMap(); private Object[] parallelDataAccessSync = new Object[100]; public volatile static boolean jvmShutdownStatus = false; public static List allChildThreadList = null; public long startTimeAAA = 0L; public OkuyamaFilesystem(String okuyamaMasterNode, boolean singleMode) throws IOException { log.info("okuyama file system init start..."); int files = 0; int dirs = 0; int blocks = 0; this.masterNodeStr = masterNodeStr; statfs = new FuseStatfs(); statfs.blocks = Integer.MAX_VALUE; statfs.blockSize = blockSize; statfs.blocksFree = Integer.MAX_VALUE; statfs.files = files + dirs; statfs.filesFree = Integer.MAX_VALUE; statfs.namelen = 2048; try { for (int idx = 0; idx < 100; idx++) { this.parallelDataAccessSync[idx] = new Object(); } client = new OkuyamaClientWrapper(singleMode); } catch (Exception e) { throw new IOException(e); } log.info("okuyama file system init end..."); } public int chmod(String path, int mode) throws FuseException { log.info("chmod " + path + " " + mode); String[] pathInfo = null; StringBuilder newPathInfo = new StringBuilder(); try { String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null || pathInfoStr.trim().equals("")) return Errno.ENOENT; pathInfo = pathInfoStr.split("\t"); pathInfo[7] = new Integer((new Integer(pathInfo[7]).intValue() & FuseStatConstants.TYPE_MASK) | (mode & FuseStatConstants.MODE_MASK)).toString(); String sep = ""; for (int i = 0; i < pathInfo.length; i++) { newPathInfo.append(sep); newPathInfo.append(pathInfo[i]); sep = "\t"; } client.setPathDetail(path.trim(), newPathInfo.toString()); } catch (FuseException fe) { throw fe; } catch (Exception e) { new FuseException(e).initErrno(FuseException.EACCES); } return 0; } public int chown(String path, int uid, int gid) throws FuseException { log.info("chown " + path + " " + uid + " " + gid); try { String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null) return Errno.ENOENT; String[] pathInfo = pathInfoStr.split("\t"); pathInfo[2] = new Integer(uid).toString(); // pathInfo[3] = new Integer(gid).toString(); // StringBuilder strBuf = new StringBuilder(100); String sep = ""; for (int i = 0; i < pathInfo.length; i++) { strBuf.append(sep); strBuf.append(pathInfo[i]); sep = "\t"; } client.setPathDetail(path.trim(), strBuf.toString()); } catch (FuseException fe) { throw fe; } catch (Exception e) { new FuseException(e).initErrno(FuseException.EACCES); } return 0; //throw new FuseException("Read Only").initErrno(FuseException.EACCES); } public int getattr(String path, FuseGetattrSetter getattrSetter) throws FuseException { log.info("getattr " + path); String[] pathInfo = null; try { String[] setInfo = new String[11]; synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { // ???????????flush? List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } } if (path.trim().equals("/")) { setInfo[1] = new Integer(FuseFtypeConstants.TYPE_DIR | 0777).toString(); pathInfo = new String[9]; pathInfo[1] = "0"; pathInfo[2] = "0"; pathInfo[3] = "0"; pathInfo[4] = "0"; pathInfo[5] = "0"; pathInfo[6] = "0"; pathInfo[8] = "0"; } else { String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null || pathInfoStr.trim().equals("")) { return Errno.ENOENT; } pathInfo = pathInfoStr.split("\t"); if (pathInfo[0].equals("file")) { setInfo[1] = new Integer(FuseFtypeConstants.TYPE_FILE | new Integer(pathInfo[7]).intValue()) .toString(); } else if (pathInfo[0].equals("dir")) { setInfo[1] = new Integer(FuseFtypeConstants.TYPE_DIR | new Integer(pathInfo[7]).intValue()) .toString(); } else { // ? client.removePathDetail(path.trim()); return Errno.ENOENT; //throw new FuseException("No such entry entry name =[" + pathInfoStr + "]").initErrno(FuseException.ENOENT); } } /* stat.nlink = 1; stat.uid = 0; stat.gid = 0; stat.size = 1000; stat.atime = 0; stat.blocks = 2; */ setInfo[0] = new Integer(path.hashCode()).toString(); // inode setInfo[2] = pathInfo[1]; //stat.nlink = Integer.parseInt(pathInfo[1]); setInfo[3] = pathInfo[2]; ///stat.uid = Integer.parseInt(pathInfo[2]); setInfo[4] = pathInfo[3]; //stat.gid = Integer.parseInt(pathInfo[3]); setInfo[5] = pathInfo[8]; // rdev setInfo[6] = pathInfo[4]; //stat.size = Integer.parseInt(pathInfo[4]); long blockCnt = Long.parseLong(setInfo[6]) / 512; if (Long.parseLong(setInfo[6]) % 512 > 0) blockCnt++; //setInfo[7] = Long.parseLong(setInfo[6]) % 512; //stat.blocks = Integer.parseInt(pathInfo[6]); setInfo[8] = pathInfo[5]; //stat.atime = Integer.parseInt(pathInfo[5]); setInfo[9] = pathInfo[5]; // mtime setInfo[10] = pathInfo[5]; // ctime getattrSetter.set(new Long(setInfo[0]).longValue(), new Integer(setInfo[1]).intValue(), new Integer(setInfo[2]).intValue(), new Integer(setInfo[3]).intValue(), new Integer(setInfo[4]).intValue(), new Integer(setInfo[5]).intValue(), new Long(setInfo[6]).longValue(), blockCnt, new Integer(setInfo[8]).intValue(), new Integer(setInfo[9]).intValue(), new Integer(setInfo[10]).intValue()); } catch (FuseException fe) { fe.printStackTrace(); throw fe; } catch (Exception e) { e.printStackTrace(); new FuseException(e).initErrno(FuseException.EACCES); } return 0; } public int getdir(String path, FuseDirFiller dirFiller) throws FuseException { log.info("getdir " + path); try { Map dirChildMap = client.getDirChild(path.trim()); if (dirChildMap == null) return Errno.ENOTDIR; int i = 0; Set entrySet = dirChildMap.entrySet(); Iterator entryIte = entrySet.iterator(); while (entryIte.hasNext()) { Map.Entry obj = (Map.Entry) entryIte.next(); String name = (String) obj.getKey(); Map metaInfo = client.getDataMetaInfo(name); boolean deleteFlg = true; if (metaInfo.size() > 1) { if (metaInfo.get("pathdetail") != null && metaInfo.get("attribute") != null) { deleteFlg = false; String[] nameCnv = name.split("/"); try { String pathInfoStrCheck = (String) metaInfo.get("pathdetail"); if (((String) obj.getValue()).equals("dir")) { dirFiller.add(nameCnv[nameCnv.length - 1], 0L, FuseFtype.TYPE_DIR); } else { dirFiller.add(nameCnv[nameCnv.length - 1], 0L, FuseFtype.TYPE_FILE); } i++; } catch (Exception ee) { deleteFlg = true; } } } if (deleteFlg) { // ??? // ?? synchronized (this.parallelDataAccessSync[((name.hashCode() << 1) >>> 1) % 100]) { try { client.removePathDetail(name); client.removeAttribute(name); String pathInfoStr = (String) metaInfo.get("pathdetail"); if (pathInfoStr != null) { String[] pathInfo = pathInfoStr.split("\t"); client.deleteValue(name, pathInfo[pathInfo.length - 2]); } client.removeDir(name); } catch (Exception innerE) { } log.fatal("broken file remove filename=[" + name + "]"); } } } } catch (FuseException fe) { throw fe; } catch (Exception e) { throw new FuseException(e); } return 0; } public int link(String from, String to) throws FuseException { log.info("link " + from + " " + to); return Errno.EACCES; } public int mkdir(String path, int mode) throws FuseException { log.info("mkdir " + path + " " + mode); try { if (client.addDir(path.trim()) == false) return Errno.EEXIST; if (client.setDirAttribute(path.trim(), "dir") == false) return Errno.EEXIST; // setPathDetail String pathType = "dir"; String pathInfoStr = ""; pathInfoStr = pathInfoStr + pathType; pathInfoStr = pathInfoStr + "\t" + "1"; pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + (System.currentTimeMillis() / 1000L); pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + mode; pathInfoStr = pathInfoStr + "\t" + "0"; //rdev pathInfoStr = pathInfoStr + "\t" + System.nanoTime(); // realKeyNodeNo if (!client.addPathDetail(path.trim(), pathInfoStr)) { return Errno.EEXIST; } } catch (FuseException fe) { throw fe; } catch (Exception e) { throw new FuseException(e); } return 0; } public int mknod(String path, int mode, int rdev) throws FuseException { log.info("mknod " + path + " " + mode + " " + rdev); // mode?8??3???????http://sourceforge.net/apps/mediawiki/fuse/index.php?title=Stat // 3??=>755??644?? String modeStr = Integer.toOctalString(mode); String pathType = ""; String fileBlockIdx = null; if (modeStr.indexOf("100") == 0) { // Regular File pathType = "file"; fileBlockIdx = "-1"; } else if (modeStr.indexOf("40") == 0) { // Directory pathType = "dir"; } else { return Errno.EINVAL; } String pathInfoStr = ""; pathInfoStr = pathInfoStr + pathType; pathInfoStr = pathInfoStr + "\t" + "1"; pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + (System.currentTimeMillis() / 1000L); pathInfoStr = pathInfoStr + "\t" + "0"; pathInfoStr = pathInfoStr + "\t" + mode; pathInfoStr = pathInfoStr + "\t" + rdev; pathInfoStr = pathInfoStr + "\t" + System.nanoTime(); // realKeyNodeNo if (fileBlockIdx != null) { pathInfoStr = pathInfoStr + "\t" + fileBlockIdx; } try { if (!client.addPathDetail(path.trim(), pathInfoStr)) { return Errno.EEXIST; } if (!client.setDirAttribute(path.trim(), pathType)) { return Errno.EEXIST; } } catch (FuseException fe) { throw fe; } catch (Exception e) { new FuseException(e); } return 0; } public int open(String path, int flags, FuseOpenSetter openSetter) throws FuseException { log.info("open " + path + " " + flags); long fileDp = System.nanoTime(); try { String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null || pathInfoStr.trim().equals("")) return Errno.ENOENT; Map openDt = new HashMap(); openDt.put("filedp", fileDp); // open??Long(File) openDt.put("pathInfoStr", pathInfoStr); openStatusMap.put(path.trim(), openDt); openSetter.setFh(openDt); } catch (FuseException fe) { throw fe; } catch (Exception e) { e.printStackTrace(); new FuseException(e); } return 0; } public int rename(String from, String to) throws FuseException { log.info("rename " + from + " " + to); String[] pathInfo = null; StringBuilder newPathInfo = new StringBuilder(); try { synchronized (this.parallelDataAccessSync[((from.hashCode() << 1) >>> 1) % 100]) { // ???????????flush? List bufferedDataFhList = writeBufFpMap.removeGroupingData(from); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } String pathInfoStr = client.getPathDetail(from.trim()); if (pathInfoStr == null || pathInfoStr.trim().equals("")) return Errno.ENOENT; pathInfo = pathInfoStr.split("\t"); if (!client.addPathDetail(to.trim(), pathInfoStr)) { return Errno.EEXIST; } if (!client.setDirAttribute(to.trim(), pathInfo[0])) { return Errno.EEXIST; } if (client.removePathDetail(from.trim()) == false) return Errno.EIO; if (client.removeAttribute(from.trim()) == false) return Errno.EIO; } } catch (FuseException fe) { throw fe; } catch (Exception e) { new FuseException(e).initErrno(FuseException.EACCES); } return 0; } public int rmdir(String path) throws FuseException { log.info("rmdir " + path); try { String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null) return Errno.ENOTDIR; Map dirChildMap = client.getDirChild(path.trim()); if (dirChildMap != null && dirChildMap.size() > 0) { return Errno.ENOTEMPTY; } if (client.removePathDetail(path.trim()) == false) return Errno.EBUSY; if (client.removeDir(path.trim()) == false) return Errno.EBUSY; } catch (Exception e) { new FuseException(e).initErrno(FuseException.EACCES); } return 0; } public int statfs(FuseStatfsSetter statfsSetter) throws FuseException { log.info("statfs " + statfsSetter); statfsSetter.set(blockSize, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, 2000); return 0; } public int symlink(String from, String to) throws FuseException { log.info("symlink " + from + " " + to); return Errno.EACCES; } public int truncate(String path, long size) throws FuseException { log.info("truncate " + path + " " + size); try { synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { // ???????????flush? List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null) return Errno.ENOENT; String[] pathInfo = pathInfoStr.split("\t"); if (new Long(pathInfo[4].trim()).longValue() > size) { client.removeValue(path.trim(), size, (Long.parseLong(pathInfo[4]) - size), pathInfo[pathInfo.length - 2]); } else { client.appendingNullData(path.trim(), size, pathInfo[pathInfo.length - 2]); } pathInfo[4] = new Long(size).toString(); pathInfo[5] = new Long(System.currentTimeMillis() / 1000L).toString(); int assistBlockSize = 0; if ((size % blockSize) > 0) { assistBlockSize = 1; } pathInfo[6] = new Long((size / blockSize) + assistBlockSize).toString(); StringBuilder strBuf = new StringBuilder(64); strBuf.append(pathInfo[0]).append("\t").append(pathInfo[1]).append("\t").append(pathInfo[2]) .append("\t").append(pathInfo[3]).append("\t").append(pathInfo[4]).append("\t") .append(pathInfo[5]).append("\t").append(pathInfo[6]).append("\t").append(pathInfo[7]) .append("\t").append(pathInfo[8]).append("\t").append(pathInfo[9]).append("\t") .append("-1"); if (!client.setPathDetail(path.trim(), strBuf.toString())) return Errno.EIO; } } catch (FuseException fe) { throw fe; } catch (Exception e) { throw new FuseException(e).initErrno(FuseException.EACCES); } return 0; } /* public int unlink(String path) throws FuseException { return 0; } */ public int unlink(String path) throws FuseException { log.info("unlink " + path); try { synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { // ???????????flush? List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } Map metaInfo = client.getDataMetaInfo(path); boolean deleteFlg = true; if (metaInfo.size() > 1) { if (metaInfo.get("pathdetail") != null && metaInfo.get("attribute") != null) { deleteFlg = false; String pathInfoStr = client.getPathDetail(path.trim()); if (pathInfoStr == null) return Errno.ENOENT; String[] pathInfo = pathInfoStr.split("\t"); if (client.removePathDetail(path.trim()) == false) return Errno.EIO; if (client.removeAttribute(path.trim()) == false) return Errno.EIO; client.deleteValue(path.trim(), pathInfo[pathInfo.length - 2]); } } if (deleteFlg) { try { client.removePathDetail(path); client.removeAttribute(path); String pathInfoStr = (String) metaInfo.get("pathdetail"); if (pathInfoStr != null) { String[] pathInfo = pathInfoStr.split("\t"); client.deleteValue(path, pathInfo[pathInfo.length - 2]); } } catch (Exception innerE) { } log.fatal("broken file remove filename=[" + path + "]"); } } } catch (Exception e) { throw new FuseException(e).initErrno(FuseException.EIO); } return 0; } public int utime(String path, int atime, int mtime) throws FuseException { log.info("utime " + path + " " + atime + " " + mtime); return 0; } public int readlink(String path, CharBuffer link) throws FuseException { log.info("readlink " + path); link.append(path); return 0; } public int write_bk(String path, Object fh, boolean isWritepage, ByteBuffer buf, long offset) throws FuseException { byte[] tmpBuf = new byte[buf.limit()]; buf.get(tmpBuf); return 0; } public int write(String path, Object fh, boolean isWritepage, ByteBuffer buf, long offset) throws FuseException { log.info("write path:" + path + " offset:" + offset + " isWritepage:" + isWritepage + " buf.limit:" + buf.limit()); //long startAA = System.nanoTime(); try { if (startTimeAAA == 0L) startTimeAAA = System.nanoTime(); // ?????????????? if (OkuyamaFilesystem.storageType == 1) return realWrite(path, fh, isWritepage, buf, offset); if (fh == null) return Errno.EBADE; synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { if (appendWriteDataBuf.containsKey(fh)) { Map appendData = (Map) appendWriteDataBuf.get(fh); ByteArrayOutputStream bBuf = (ByteArrayOutputStream) appendData.get("buf"); long bOffset = ((Long) appendData.get("offset")).longValue(); if ((bOffset + bBuf.size()) == offset) { byte[] tmpBuf = new byte[buf.limit()]; buf.get(tmpBuf); bBuf.write(tmpBuf); // ?????????????????? if (bBuf.size() >= writeBufferSize) { // ??????? appendWriteDataBuf.remove(fh); String bPath = (String) appendData.get("path"); Object bFh = (Object) appendData.get("fh"); boolean bIsWritepage = ((Boolean) appendData.get("isWritepage")).booleanValue(); int ret = this.realWrite(bPath, bFh, bIsWritepage, bBuf, bOffset); return ret; } else { return 0; } } else { // offset????????????? appendWriteDataBuf.remove(fh); String bPath = (String) appendData.get("path"); Object bFh = (Object) appendData.get("fh"); boolean bIsWritepage = ((Boolean) appendData.get("isWritepage")).booleanValue(); int realWriteRet = this.realWrite(bPath, bFh, bIsWritepage, bBuf, bOffset); if (realWriteRet == 0) { int retI = this.realWrite(path, fh, isWritepage, buf, offset); return retI; } else { return realWriteRet; } } } else { Map appendData = new HashMap(); appendData.put("path", path); appendData.put("fh", fh); appendData.put("isWritepage", isWritepage); ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 1024 * 10 + 8192); byte[] tmpByte = new byte[buf.limit()]; buf.get(tmpByte); baos.write(tmpByte); appendData.put("buf", baos); appendData.put("offset", offset); this.appendWriteDataBuf.put(fh, appendData); this.writeBufFpMap.addGroupingData(path, fh); return 0; } } } catch (Exception e) { throw new FuseException(e); } finally { } } public int realWrite(String path, Object fh, boolean isWritepage, ByteBuffer buf, long offset) throws FuseException { byte[] writeData = new byte[buf.limit()]; buf.get(writeData); return realWrite(path, fh, isWritepage, writeData, offset); } public int realWrite(String path, Object fh, boolean isWritepage, ByteArrayOutputStream buf, long offset) throws FuseException { byte[] data = buf.toByteArray(); return realWrite(path, fh, isWritepage, data, offset); } public int realWrite(String path, Object fh, boolean isWritepage, byte[] writeData, long offset) throws FuseException { //log.info("realWrite path:" + path + " offset:" + offset + " isWritepage:" + isWritepage + " buf.limit:" + writeData.length); if (fh == null) return Errno.EBADE; //long start = System.nanoTime(); try { /*System.out.println("--------------- start --------------- "); for (int i = 0; i < writeData.length; i++) { System.out.println("path=" + path + " offet=" + offset +" writeData[" + i + "]=" + writeData[i]); } System.out.println("--------------- end --------------- ");*/ String pathTrimStr = path.trim(); String pathInfoStr = (String) client.getPathDetail(pathTrimStr); if (pathInfoStr == null) return Errno.ENOENT; String[] pathInfo = pathInfoStr.split("\t"); //long end2 = System.nanoTime(); //System.out.println("Time2=" + (end2 - start)); long writeLastBlockIdx = -1L; if (writeData == null || writeData.length < 1) { log.error("write data nothing = realWrite path:" + path + " offset:" + offset + " isWritepage:" + isWritepage + " buf.limit:" + writeData.length); } else { int idx = writeData.length; writeLastBlockIdx = client.writeValue(pathTrimStr, offset, writeData, writeData.length, pathInfo[pathInfo.length - 2], new Long(pathInfo[10]).longValue()); } //long end3 = System.nanoTime(); //System.out.println("Time3=" + (end3 - end2)); if (Long.parseLong(pathInfo[4]) < 1) { pathInfo[4] = new Long(writeData.length).toString(); } else if (Long.parseLong(pathInfo[4]) < new Long(offset + new Long(writeData.length).longValue()) .longValue()) { pathInfo[4] = new Long(offset + new Long(writeData.length).longValue()).toString(); } pathInfo[5] = new Long(System.currentTimeMillis() / 1000L).toString(); int assistBlockSize = 0; if (((Long.parseLong(pathInfo[4]) + writeData.length) % blockSize) > 0) { assistBlockSize = 1; } pathInfo[6] = new Long(((Long.parseLong(pathInfo[4]) + writeData.length) / blockSize) + assistBlockSize) .toString(); StringBuilder strBuf = new StringBuilder(64); strBuf.append(pathInfo[0]).append("\t").append(pathInfo[1]).append("\t").append(pathInfo[2]) .append("\t").append(pathInfo[3]).append("\t").append(pathInfo[4]).append("\t") .append(pathInfo[5]).append("\t").append(pathInfo[6]).append("\t").append(pathInfo[7]) .append("\t").append(pathInfo[8]).append("\t").append(pathInfo[9]).append("\t"); if (new Long(pathInfo[10]).longValue() < writeLastBlockIdx) { strBuf.append(writeLastBlockIdx); } else { strBuf.append(pathInfo[10]); } client.setPathDetail(pathTrimStr, strBuf.toString()); //long end4 = System.nanoTime(); //System.out.println("Time4=" + (end4 - end3)); } catch (FuseException fe) { throw fe; } catch (Exception e) { new FuseException(e); } //long end = System.nanoTime(); //System.out.println("Time=" + (end - start)); return 0; } public int read(String path, Object fh, ByteBuffer buf, long offset) throws FuseException { /*long start1 = 0L; long start2 = 0L; long start3 = 0L; long start4 = 0L; long start5 = 0L; long end2 = 0L; long end3 = 0L; long end4 = 0L; long end5 = 0L; */ //start1 = System.nanoTime(); //start2 = System.nanoTime(); log.info("read:" + path + " offset:" + offset + " buf.limit:" + buf.limit()); if (fh == null) return Errno.EBADE; try { String trimToPath = path.trim(); synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { // ???????????flush? List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } String pathInfoStr = (String) client.getPathDetail(trimToPath); String[] pathInfo = pathInfoStr.split("\t"); long nowSize = Long.parseLong(pathInfo[4]); int readLen = client.readValue(trimToPath, offset, buf.limit(), pathInfo[pathInfo.length - 2], buf); if (readLen == -1 || readLen < 1) { log.info("read data nothing read=" + "read:" + path + " offset:" + offset + " buf.limit:" + buf.limit()); } } } catch (FuseException fe) { throw fe; } catch (Exception e) { new FuseException(e); } return 0; } public int release(String path, Object fh, int flags) throws FuseException { log.info("release " + path + " " + fh + " " + flags); synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } openStatusMap.remove(path.trim()); this.fixNoCommitData(fh); } return 0; } public int flush(String path, Object fh) throws FuseException { synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { log.info("flush " + path + " " + fh); List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } this.fixNoCommitData(fh); } return 0; } public int fsync(String path, Object fh, boolean isDatasync) throws FuseException { synchronized (this.parallelDataAccessSync[((path.hashCode() << 1) >>> 1) % 100]) { log.info("fsync " + path + " " + fh + " " + isDatasync); List bufferedDataFhList = writeBufFpMap.removeGroupingData(path); if (bufferedDataFhList != null) { for (int idx = 0; idx < bufferedDataFhList.size(); idx++) { Object bFh = bufferedDataFhList.get(idx); this.fixNoCommitData(bFh); } } this.fixNoCommitData(fh); } return 0; } private int fixNoCommitData(Object fh) throws FuseException { if (appendWriteDataBuf.containsKey(fh)) { Map appendData = (Map) appendWriteDataBuf.remove(fh); if (appendData != null) { String bPath = (String) appendData.get("path"); Object bFh = (Object) appendData.get("fh"); boolean bIsWritepage = ((Boolean) appendData.get("isWritepage")).booleanValue(); ByteArrayOutputStream bBuf = (ByteArrayOutputStream) appendData.get("buf"); long bOffset = ((Long) appendData.get("offset")).longValue(); int realWriteRet = this.realWrite(bPath, bFh, bIsWritepage, bBuf, bOffset); return realWriteRet; } } return 0; } public int getxattr(String path, String name, ByteBuffer dst) throws FuseException, BufferOverflowException { return 0; } public int getxattrsize(String path, String name, FuseSizeSetter sizeSetter) throws FuseException { return 0; } public int listxattr(String path, XattrLister lister) throws FuseException { return 0; } public int removexattr(String path, String name) throws FuseException { return 0; } public int setxattr(String path, String name, ByteBuffer value, int flags) throws FuseException { return 0; } }