オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Diff of /trunk/1.6.x/ccs-patch/fs/realpath.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/1.5.x/ccs-patch/fs/realpath.c revision 652 by kumaneko, Mon Nov 5 07:48:31 2007 UTC trunk/1.6.x/ccs-patch/fs/realpath.c revision 1031 by kumaneko, Tue Mar 11 04:38:56 2008 UTC
# Line 3  Line 3 
3   *   *
4   * Get the canonicalized absolute pathnames. The basis for SAKURA and TOMOYO.   * Get the canonicalized absolute pathnames. The basis for SAKURA and TOMOYO.
5   *   *
6   * Copyright (C) 2005-2007  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.5.2-pre   2007/10/19   * Version: 1.6.0-pre   2008/03/11
9   *   *
10   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
11   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 32  static const int lookup_flags = LOOKUP_F Line 32  static const int lookup_flags = LOOKUP_F
32  #include <linux/proc_fs.h>  #include <linux/proc_fs.h>
33  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
34    
 extern int sbin_init_started;  
   
35  /***** realpath handler *****/  /***** realpath handler *****/
36    
37  /*  /*
# Line 83  static int GetAbsolutePath(struct dentry Line 81  static int GetAbsolutePath(struct dentry
81                          continue;                          continue;
82                  }                  }
83                  if (is_dir) {                  if (is_dir) {
84                          is_dir = 0; *--end = '/'; buflen--;                          is_dir = false; *--end = '/'; buflen--;
85                  }                  }
86                  parent = dentry->d_parent;                  parent = dentry->d_parent;
87                  {                  {
# Line 183  int realpath_from_dentry2(struct dentry Line 181  int realpath_from_dentry2(struct dentry
181  /* These functions use ccs_alloc(), so caller must ccs_free() if these functions didn't return NULL. */  /* These functions use ccs_alloc(), so caller must ccs_free() if these functions didn't return NULL. */
182  char *realpath_from_dentry(struct dentry *dentry, struct vfsmount *mnt)  char *realpath_from_dentry(struct dentry *dentry, struct vfsmount *mnt)
183  {  {
184          char *buf = ccs_alloc(CCS_MAX_PATHNAME_LEN);          char *buf = ccs_alloc(sizeof(struct ccs_page_buffer));
185          if (buf && realpath_from_dentry2(dentry, mnt, buf, CCS_MAX_PATHNAME_LEN - 1) == 0) return buf;          if (buf && realpath_from_dentry2(dentry, mnt, buf, CCS_MAX_PATHNAME_LEN - 1) == 0) return buf;
186          ccs_free(buf);          ccs_free(buf);
187          return NULL;          return NULL;
# Line 193  char *realpath(const char *pathname) Line 191  char *realpath(const char *pathname)
191  {  {
192          struct nameidata nd;          struct nameidata nd;
193          if (pathname && path_lookup(pathname, lookup_flags, &nd) == 0) {          if (pathname && path_lookup(pathname, lookup_flags, &nd) == 0) {
194    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
195                    char *buf = realpath_from_dentry(nd.path.dentry, nd.path.mnt);
196                    path_put(&nd.path);
197    #else
198                  char *buf = realpath_from_dentry(nd.dentry, nd.mnt);                  char *buf = realpath_from_dentry(nd.dentry, nd.mnt);
199                  path_release(&nd);                  path_release(&nd);
200    #endif
201                  return buf;                  return buf;
202          }          }
203          return NULL;          return NULL;
# Line 204  char *realpath_nofollow(const char *path Line 207  char *realpath_nofollow(const char *path
207  {  {
208          struct nameidata nd;          struct nameidata nd;
209          if (pathname && path_lookup(pathname, lookup_flags ^ LOOKUP_FOLLOW, &nd) == 0) {          if (pathname && path_lookup(pathname, lookup_flags ^ LOOKUP_FOLLOW, &nd) == 0) {
210    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
211                    char *buf = realpath_from_dentry(nd.path.dentry, nd.path.mnt);
212                    path_put(&nd.path);
213    #else
214                  char *buf = realpath_from_dentry(nd.dentry, nd.mnt);                  char *buf = realpath_from_dentry(nd.dentry, nd.mnt);
215                  path_release(&nd);                  path_release(&nd);
216    #endif
217                  return buf;                  return buf;
218          }          }
219          return NULL;          return NULL;
# Line 243  void *alloc_element(const unsigned int s Line 251  void *alloc_element(const unsigned int s
251          if (word_aligned_size > PAGE_SIZE) return NULL;          if (word_aligned_size > PAGE_SIZE) return NULL;
252          mutex_lock(&lock);          mutex_lock(&lock);
253          if (buf_used_len + word_aligned_size > PAGE_SIZE) {          if (buf_used_len + word_aligned_size > PAGE_SIZE) {
254                  if ((ptr = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) {                  if ((ptr = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) {
255                          printk("ERROR: Out of memory for alloc_element().\n");                          printk("ERROR: Out of memory for alloc_element().\n");
256                          if (!sbin_init_started) panic("MAC Initialization failed.\n");                          if (!sbin_init_started) panic("MAC Initialization failed.\n");
257                  } else {                  } else {
                         memset(ptr, 0, PAGE_SIZE);  
258                          buf = ptr;                          buf = ptr;
259                          allocated_memory_for_elements += PAGE_SIZE;                          allocated_memory_for_elements += PAGE_SIZE;
260                          buf_used_len = word_aligned_size;                          buf_used_len = word_aligned_size;
# Line 271  void *alloc_element(const unsigned int s Line 278  void *alloc_element(const unsigned int s
278  /***** Shared memory allocator. *****/  /***** Shared memory allocator. *****/
279    
280  static unsigned int allocated_memory_for_savename = 0;  static unsigned int allocated_memory_for_savename = 0;
281    static unsigned int allocated_memory_for_pool = 0;
282    
283  unsigned int GetMemoryUsedForSaveName(void)  unsigned int GetMemoryUsedForSaveName(void)
284  {  {
285          return allocated_memory_for_savename;          return allocated_memory_for_savename + allocated_memory_for_pool;
286  }  }
287    
288  #define MAX_HASH 256  #define MAX_HASH 256
289    
290  struct name_entry {  struct name_entry {
291          struct name_entry *next; /* Pointer to next record. NULL if none.             */          struct list1_head list;
292          struct path_info entry;          struct path_info entry;
293  };  };
294    
295  struct free_memory_block_list {  struct free_memory_block_list {
296          struct free_memory_block_list *next; /* Pointer to next record. NULL if none. */          struct list_head list;
297          char *ptr;                           /* Pointer to a free area.               */          char *ptr;                           /* Pointer to a free area.               */
298          int len;                             /* Length of the area.                   */          int len;                             /* Length of the area.                   */
299  };  };
300    
301    static struct list1_head name_list[MAX_HASH]; /* The list of names. */
302    
303  /* Keep the given name on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned name. */  /* Keep the given name on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned name. */
304  const struct path_info *SaveName(const char *name)  const struct path_info *SaveName(const char *name)
305  {  {
306          static struct free_memory_block_list fmb_list = { NULL, NULL, 0 };          static LIST_HEAD(fmb_list);
         static struct name_entry name_list[MAX_HASH]; /* The list of names. */  
307          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
308          struct name_entry *ptr, *prev = NULL;          struct name_entry *ptr;
309          unsigned int hash;          unsigned int hash;
310          struct free_memory_block_list *fmb = &fmb_list;          struct free_memory_block_list *fmb;
311          int len;          int len;
312          static int first_call = 1;          char *cp;
313          if (!name) return NULL;          if (!name) return NULL;
314          len = strlen(name) + 1;          len = strlen(name) + 1;
315          if (len > CCS_MAX_PATHNAME_LEN) {          if (len > CCS_MAX_PATHNAME_LEN) {
# Line 309  const struct path_info *SaveName(const c Line 318  const struct path_info *SaveName(const c
318          }          }
319          hash = full_name_hash((const unsigned char *) name, len - 1);          hash = full_name_hash((const unsigned char *) name, len - 1);
320          mutex_lock(&lock);          mutex_lock(&lock);
321          if (first_call) {          list1_for_each_entry(ptr, &name_list[hash % MAX_HASH], list) {
                 int i;  
                 first_call = 0;  
                 memset(&name_list, 0, sizeof(name_list));  
                 for (i = 0; i < MAX_HASH; i++) {  
                         name_list[i].entry.name = "/";  
                         fill_path_info(&name_list[i].entry);  
                 }  
                 if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) panic("Bad size.");  
         }  
         ptr = &name_list[hash % MAX_HASH];  
         while (ptr) {  
322                  if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out;                  if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out;
                 prev = ptr; ptr = ptr->next;  
323          }          }
324          while (len > fmb->len) {          list_for_each_entry(fmb, &fmb_list, list) {
325                  if (fmb->next) {                  if (len <= fmb->len) goto ready;
                         fmb = fmb->next;  
                 } else {  
                         char *cp;  
                         if ((cp = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL || (fmb->next = alloc_element(sizeof(*fmb))) == NULL) {  
                                 kfree(cp);  
                                 printk("ERROR: Out of memory for SaveName().\n");  
                                 if (!sbin_init_started) panic("MAC Initialization failed.\n");  
                                 goto out; /* ptr == NULL */  
                         }  
                         memset(cp, 0, PAGE_SIZE);  
                         allocated_memory_for_savename += PAGE_SIZE;  
                         fmb = fmb->next;  
                         fmb->ptr = cp;  
                         fmb->len = PAGE_SIZE;  
                 }  
326          }          }
327          if ((ptr = alloc_element(sizeof(*ptr))) == NULL) goto out;          cp = kzalloc(PAGE_SIZE, GFP_KERNEL);
328            fmb = kzalloc(sizeof(*fmb), GFP_KERNEL);
329            if (!cp || !fmb) {
330                    kfree(cp);
331                    kfree(fmb);
332                    printk("ERROR: Out of memory for SaveName().\n");
333                    if (!sbin_init_started) panic("MAC Initialization failed.\n");
334                    ptr = NULL;
335                    goto out;
336            }
337            allocated_memory_for_savename += PAGE_SIZE;
338            list_add(&fmb->list, &fmb_list);
339            fmb->ptr = cp;
340            fmb->len = PAGE_SIZE;
341     ready:
342            ptr = alloc_element(sizeof(*ptr));
343            if (!ptr) goto out;
344          ptr->entry.name = fmb->ptr;          ptr->entry.name = fmb->ptr;
345          memmove(fmb->ptr, name, len);          memmove(fmb->ptr, name, len);
346          fill_path_info(&ptr->entry);          fill_path_info(&ptr->entry);
347          fmb->ptr += len;          fmb->ptr += len;
348          fmb->len -= len;          fmb->len -= len;
349          prev->next = ptr; /* prev != NULL because name_list is not empty. */          list1_add_tail_mb(&ptr->list, &name_list[hash % MAX_HASH]);
350          if (fmb->len == 0) {          if (fmb->len == 0) {
351                  struct free_memory_block_list *ptr = &fmb_list;                  list_del(&fmb->list);
352                  while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next;                  kfree(fmb);
353          }          }
354   out:   out:
355          mutex_unlock(&lock);          mutex_unlock(&lock);
# Line 372  static struct kmem_cache *ccs_cachep = N Line 370  static struct kmem_cache *ccs_cachep = N
370  static kmem_cache_t *ccs_cachep = NULL;  static kmem_cache_t *ccs_cachep = NULL;
371  #endif  #endif
372    
373    #ifdef CCS_MAX_RESERVED_PAGES
374    #define MAX_CCS_PAGE_BUFFER_POOL (CCS_MAX_RESERVED_PAGES)
375    #else
376    #define MAX_CCS_PAGE_BUFFER_POOL 10
377    #endif
378    
379    static struct ccs_page_buffer *ccs_page_buffer_pool[MAX_CCS_PAGE_BUFFER_POOL];
380    static bool ccs_page_buffer_pool_in_use[MAX_CCS_PAGE_BUFFER_POOL];
381    
382  void __init realpath_Init(void)  void __init realpath_Init(void)
383  {  {
384            int i;
385            if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) panic("Bad size.");
386            if (sizeof(struct path_info_with_data) > sizeof(struct ccs_page_buffer)) panic("Bad size.");
387  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
388          ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL);          ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL);
389  #else  #else
390          ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL);          ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL);
391  #endif  #endif
392          if (!ccs_cachep) panic("Can't create cache.\n");          if (!ccs_cachep) panic("Can't create cache.\n");
393            for (i = 0; i < MAX_HASH; i++) {
394                    INIT_LIST1_HEAD(&name_list[i]);
395            }
396            INIT_LIST1_HEAD(&KERNEL_DOMAIN.acl_info_list);
397            KERNEL_DOMAIN.domainname = SaveName(ROOT_NAME);
398            list1_add_tail_mb(&KERNEL_DOMAIN.list, &domain_list);
399            if (FindDomain(ROOT_NAME) != &KERNEL_DOMAIN) panic("Can't register KERNEL_DOMAIN");
400            memset(ccs_page_buffer_pool, 0, sizeof(ccs_page_buffer_pool));
401            for (i = 0; i < MAX_CCS_PAGE_BUFFER_POOL; i++) ccs_page_buffer_pool_in_use[i] = false;
402  }  }
403    
404  static LIST_HEAD(cache_list);  static LIST_HEAD(cache_list);
# Line 404  static int round2(size_t size) Line 423  static int round2(size_t size)
423  }  }
424  #endif  #endif
425    
426    static spinlock_t ccs_page_buffer_pool_lock = SPIN_LOCK_UNLOCKED;
427    
428  void *ccs_alloc(const size_t size)  void *ccs_alloc(const size_t size)
429  {  {
430          void *ret = kmalloc(size, GFP_KERNEL);          int i;
431          if (ret) {          void *ret;
432                  struct cache_entry *new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL);          struct cache_entry *new_entry;
433                  if (!new_entry) {          if (size != sizeof(struct ccs_page_buffer)) goto normal;
434                          kfree(ret); ret = NULL;          for (i = 0; i < MAX_CCS_PAGE_BUFFER_POOL; i++) {
435                  } else {                  struct ccs_page_buffer *ptr;
436                          INIT_LIST_HEAD(&new_entry->list);                  if (ccs_page_buffer_pool_in_use[i]) continue;
437                          new_entry->ptr = ret;                  spin_lock(&ccs_page_buffer_pool_lock);
438                    if (ccs_page_buffer_pool_in_use[i]) {
439                            spin_unlock(&ccs_page_buffer_pool_lock);
440                            continue;
441                    }
442                    ccs_page_buffer_pool_in_use[i] = true;
443                    spin_unlock(&ccs_page_buffer_pool_lock);
444                    ptr = ccs_page_buffer_pool[i];
445                    if (!ptr) {
446                            ptr = kmalloc(sizeof(struct ccs_page_buffer), GFP_KERNEL);
447                            spin_lock(&ccs_page_buffer_pool_lock);
448                            if (ptr) {
449  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
450                          new_entry->size = ksize(ret);                                  allocated_memory_for_pool += ksize(ptr);
451  #else  #else
452                          new_entry->size = round2(size);                                  allocated_memory_for_pool += round2(sizeof(struct ccs_page_buffer));
453  #endif  #endif
454                          spin_lock(&cache_list_lock);                          } else {
455                          list_add_tail(&new_entry->list, &cache_list);                                  ccs_page_buffer_pool_in_use[i] = false;
456                          dynamic_memory_size += new_entry->size;                          }
457                          spin_unlock(&cache_list_lock);                          spin_unlock(&ccs_page_buffer_pool_lock);
458                          memset(ret, 0, size);                          if (!ptr) goto normal;
459                            ccs_page_buffer_pool[i] = ptr;
460                            printk(KERN_DEBUG "Allocated permanent buffer %d/%d\n", i, MAX_CCS_PAGE_BUFFER_POOL);
461                  }                  }
462                    memset(ptr, 0, sizeof(struct ccs_page_buffer));
463                    return ptr;
464          }          }
465     normal:
466            ret = kzalloc(size, GFP_KERNEL);
467            if (!ret) goto out;
468            new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL);
469            if (!new_entry) {
470                    kfree(ret); ret = NULL;
471                    goto out;
472            }
473            INIT_LIST_HEAD(&new_entry->list);
474            new_entry->ptr = ret;
475    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
476            new_entry->size = ksize(ret);
477    #else
478            new_entry->size = round2(size);
479    #endif
480            spin_lock(&cache_list_lock);
481            list_add_tail(&new_entry->list, &cache_list);
482            dynamic_memory_size += new_entry->size;
483            spin_unlock(&cache_list_lock);
484     out:
485          return ret;          return ret;
486  }  }
487    
488  void ccs_free(const void *p)  void ccs_free(const void *p)
489  {  {
490            int i;
491          struct list_head *v;          struct list_head *v;
492          struct cache_entry *entry = NULL;          struct cache_entry *entry = NULL;
493          if (!p) return;          if (!p) return;
494            for (i = 0; i < MAX_CCS_PAGE_BUFFER_POOL; i++) {
495                    bool done;
496                    if (p != ccs_page_buffer_pool[i]) continue;
497                    spin_lock(&ccs_page_buffer_pool_lock);
498                    done = ccs_page_buffer_pool_in_use[i];
499                    if (done) ccs_page_buffer_pool_in_use[i] = false;
500                    spin_unlock(&ccs_page_buffer_pool_lock);
501                    if (done) return;
502            }
503          spin_lock(&cache_list_lock);          spin_lock(&cache_list_lock);
504          list_for_each(v, &cache_list) {          list_for_each(v, &cache_list) {
505                  entry = list_entry(v, struct cache_entry, list);                  entry = list_entry(v, struct cache_entry, list);

Legend:
Removed from v.652  
changed lines
  Added in v.1031

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26