00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdXrootdFileCVSID = "$Id: XrdXrootdFile.cc 24468 2008-06-22 16:47:03Z ganis $";
00014
00015 #include <inttypes.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <unistd.h>
00019 #include <netinet/in.h>
00020 #include <sys/types.h>
00021 #include <sys/stat.h>
00022
00023 #include "XrdSys/XrdSysPthread.hh"
00024 #include "XrdSfs/XrdSfsInterface.hh"
00025 #include "XrdXrootd/XrdXrootdFile.hh"
00026 #include "XrdXrootd/XrdXrootdFileLock.hh"
00027 #define TRACELINK this
00028 #include "XrdXrootd/XrdXrootdTrace.hh"
00029
00030
00031
00032
00033
00034 #ifndef NODEBUG
00035 extern XrdOucTrace *XrdXrootdTrace;
00036 #endif
00037
00038 XrdXrootdFileLock *XrdXrootdFile::Locker;
00039
00040 int XrdXrootdFile::sfOK = 1;
00041 const char *XrdXrootdFile::TraceID = "File";
00042 const char *XrdXrootdFileTable::TraceID = "FileTable";
00043
00044
00045
00046
00047
00048
00049
00050
00051 XrdXrootdFile::XrdXrootdFile(char *id, XrdSfsFile *fp, char mode, char async,
00052 int sfok, struct stat *sP)
00053 {
00054 static XrdSysMutex seqMutex;
00055 struct stat buf;
00056 off_t mmSize;
00057 int i;
00058
00059 XrdSfsp = fp;
00060 mmAddr = 0;
00061 FileMode = mode;
00062 AsyncMode= async;
00063 ID = id;
00064 FileID = 0;
00065 readCnt = 0;
00066 writeCnt = 0;
00067
00068
00069
00070 if (fp->fctl(SFS_FCTL_GETFD, 0, fp->error) != SFS_OK) fdNum = -1;
00071 else fdNum = fp->error.getErrInfo();
00072 sfEnabled = (sfOK && sfok && fdNum >= 0 ? 1 : 0);
00073
00074
00075
00076 if (fp->getMmap((void **)&mmAddr, mmSize) != SFS_OK) isMMapped = 0;
00077 else {isMMapped = (mmSize ? 1 : 0);
00078 fSize = static_cast<long long>(mmSize);
00079 }
00080
00081
00082
00083 if (!sP) sP = &buf;
00084 fp->stat(sP);
00085 if (!isMMapped) fSize = static_cast<long long>(sP->st_size);
00086
00087
00088
00089
00090 if (sP->st_dev != 0 || sP->st_ino != 0)
00091 {i = bin2hex( FileKey, (char *)&sP->st_dev, sizeof(sP->st_dev));
00092 i = bin2hex(&FileKey[i],(char *)&sP->st_ino, sizeof(sP->st_ino));
00093 }
00094 else if (fdNum > 0)
00095 {strcpy( FileKey, "fdno");
00096 bin2hex(&FileKey[4], (char *)&fdNum, sizeof(fdNum));
00097 }
00098 else {strcpy( FileKey, "sfsp");
00099 bin2hex(&FileKey[4], (char *)&XrdSfsp, sizeof(XrdSfsp));
00100 }
00101 }
00102
00103
00104
00105
00106
00107 XrdXrootdFile::~XrdXrootdFile()
00108 {
00109 char *fn;
00110
00111 if (XrdSfsp) {Locker->Unlock(this);
00112 if (TRACING(TRACE_FS))
00113 {if (!(fn = (char *)XrdSfsp->FName())) fn = (char *)"?";
00114 TRACEI(FS, "closing " <<FileMode <<' ' <<fn);
00115 }
00116 delete XrdSfsp;
00117 XrdSfsp = 0;
00118 }
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 XrdXrootdFileTable::~XrdXrootdFileTable()
00133 {
00134 int i;
00135
00136
00137
00138 for (i = 0; i < XRD_FTABSIZE; i++) if (FTab[i]) Del(i);
00139
00140
00141
00142 if (XTab)
00143 {for (i = 0; i < XTnum; i++) if (XTab[i]) Del(i+XRD_FTABSIZE);
00144 free(*XTab);
00145 }
00146 }
00147
00148
00149
00150
00151
00152 int XrdXrootdFileTable::Add(XrdXrootdFile *fp)
00153 {
00154 const int allocsz = XRD_FTABSIZE*sizeof(fp);
00155 XrdXrootdFile **newXTab, **oldXTab;
00156 int i;
00157
00158
00159
00160 for (i = FTfree; i < XRD_FTABSIZE; i++) if (!FTab[i]) break;
00161
00162 if (i < XRD_FTABSIZE)
00163 {FTab[i] = fp; FTfree = i+1; return i;}
00164
00165
00166
00167 if (!XTab)
00168 {if (!(XTab = (XrdXrootdFile **)malloc(allocsz))) return -1;
00169 memset((void *)XTab, 0, allocsz);
00170 XTnum = XRD_FTABSIZE;
00171 XTfree = 1;
00172 XTab[0] = fp;
00173 return XRD_FTABSIZE;
00174 }
00175
00176
00177
00178 for (i = XTfree; i < XTnum; i++) if (!XTab[i]) break;
00179 if (i < XTnum)
00180 {XTab[i] = fp; XTfree = i+1; return i+XRD_FTABSIZE;}
00181
00182
00183
00184 if (!(newXTab = (XrdXrootdFile **)malloc(XTnum*sizeof(XrdXrootdFile *)+allocsz)))
00185 return -1;
00186 memcpy((void *)newXTab, (const void *)XTab, XTnum*sizeof(XrdXrootdFile *));
00187 memset((void *)(newXTab+XTnum), 0, allocsz);
00188 oldXTab = XTab;
00189 XTab = newXTab;
00190 XTab[XTnum] = fp;
00191 i = XTnum;
00192 XTfree = XTnum+1;
00193 XTnum += XRD_FTABSIZE;
00194 free(oldXTab);
00195 return i+XRD_FTABSIZE;
00196 }
00197
00198
00199
00200
00201
00202 void XrdXrootdFileTable::Del(int fnum)
00203 {
00204 XrdXrootdFile *fp;
00205
00206 if (fnum < XRD_FTABSIZE)
00207 {fp = FTab[fnum];
00208 FTab[fnum] = 0;
00209 if (fnum < FTfree) FTfree = fnum;
00210 } else {
00211 fnum -= XRD_FTABSIZE;
00212 if (XTab && fnum < XTnum)
00213 {fp = XTab[fnum];
00214 XTab[fnum] = 0;
00215 if (fnum < XTfree) XTfree = fnum;
00216 }
00217 else fp = 0;
00218 }
00219
00220 if (fp) delete fp;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 int XrdXrootdFile::bin2hex(char *outbuff, char *inbuff, int inlen)
00231 {
00232 static char hv[] = "0123456789abcdef";
00233 int i, j = 0;
00234
00235
00236
00237 for (i = 0; i < inlen; i++) if (inbuff[i]) break;
00238 if (i >= inlen)
00239 {outbuff[0] = '0'; outbuff[1] = '\0'; return 1;}
00240
00241
00242
00243 for (i = i; i < inlen; i++)
00244 {outbuff[j++] = hv[(inbuff[i] >> 4) & 0x0f];
00245 outbuff[j++] = hv[ inbuff[i] & 0x0f];
00246 }
00247 outbuff[j] = '\0';
00248 return j;
00249 }