00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <stdlib.h>
00013 #include <time.h>
00014 #include <pthread.h>
00015
00016 #ifndef _GNU_SOURCE
00017 #define _GNU_SOURCE
00018 #endif
00019 #include <sys/statvfs.h>
00020 #include "XrdOuc/XrdOucHash.hh"
00021
00022 #ifdef __cplusplus
00023 extern "C" {
00024 #endif
00025
00026 struct XrdFfsFsInfo {
00027 time_t t;
00028
00029 fsblkcnt_t f_blocks, f_bavail, f_bfree;
00030 };
00031
00032 pthread_mutex_t XrdFfsFsinfo_cache_mutex_wr = PTHREAD_MUTEX_INITIALIZER;
00033 pthread_mutex_t XrdFfsFsinfo_cache_mutex_rd = PTHREAD_MUTEX_INITIALIZER;
00034
00035 XrdOucHash<struct XrdFfsFsInfo> XrdFfsFsinfoHtab;
00036
00037 int XrdFfsFsinfo_cache_search(int (*func)(const char*, const char*, struct statvfs*, uid_t), const char* rdrurl, const char* path, struct statvfs *stbuf, uid_t user_uid)
00038 {
00039 struct XrdFfsFsInfo *s;
00040 int wlock, rc = 0;
00041 const char *p;
00042 char* sname;
00043
00044 wlock = pthread_mutex_trylock(&XrdFfsFsinfo_cache_mutex_wr);
00045 pthread_mutex_lock(&XrdFfsFsinfo_cache_mutex_rd);
00046
00047 p=strstr(path, "oss.cgroup=");
00048 if (p != NULL && p[11] != '\0')
00049 sname = strdup(p+11);
00050 else
00051 sname = strdup(" ");
00052 s = XrdFfsFsinfoHtab.Find(sname);
00053 if (s != NULL)
00054 {
00055 stbuf->f_blocks = s->f_blocks;
00056 stbuf->f_bavail = s->f_bavail;
00057 stbuf->f_bfree = s->f_bfree;
00058 rc = 0;
00059 }
00060 else
00061 {
00062 rc = (*func)(rdrurl, path, stbuf, user_uid);
00063 s = (struct XrdFfsFsInfo*) malloc(sizeof(struct XrdFfsFsInfo));
00064 s->t = 0;
00065 }
00066
00067 pthread_mutex_unlock(&XrdFfsFsinfo_cache_mutex_rd);
00068 if (wlock == 0)
00069 {
00070 time_t curr_time = time(NULL);
00071 if (curr_time - s->t > 120)
00072 {
00073 if (s->t != 0)
00074 rc = (*func)(rdrurl, path, stbuf, user_uid);
00075
00076 pthread_mutex_lock(&XrdFfsFsinfo_cache_mutex_rd);
00077 s->t = curr_time;
00078 s->f_blocks = stbuf->f_blocks;
00079 s->f_bavail = stbuf->f_bavail;
00080 s->f_bfree = stbuf->f_bfree;
00081
00082 if (s->f_blocks != 0)
00083 XrdFfsFsinfoHtab.Rep(sname, s, 0, (XrdOucHash_Options)(Hash_default | Hash_keepdata));
00084 pthread_mutex_unlock(&XrdFfsFsinfo_cache_mutex_rd);
00085 }
00086 pthread_mutex_unlock(&XrdFfsFsinfo_cache_mutex_wr);
00087 }
00088 free(sname);
00089 return rc;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #ifdef __cplusplus
00118 }
00119 #endif