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

Subversion リポジトリの参照

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

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

trunk/ccs-patch/fs/realpath.c revision 111 by kumaneko, Wed Feb 28 11:45:08 2007 UTC trunk/1.6.x/ccs-patch/fs/realpath.c revision 1015 by kumaneko, Tue Mar 4 04:04:39 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.3.2   2007/02/14   * Version: 1.6.0-pre   2008/03/04
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 54  static int GetAbsolutePath(struct dentry Line 52  static int GetAbsolutePath(struct dentry
52  {  {
53          char *start = buffer;          char *start = buffer;
54          char *end = buffer + buflen;          char *end = buffer + buflen;
55          int is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));          bool is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
56    
57          if (buflen < 256) goto out;          if (buflen < 256) goto out;
58    
# Line 167  int realpath_from_dentry2(struct dentry Line 165  int realpath_from_dentry2(struct dentry
165          struct dentry *d_dentry;          struct dentry *d_dentry;
166          struct vfsmount *d_mnt;          struct vfsmount *d_mnt;
167          if (!dentry || !mnt || !newname || newname_len <= 0) return -EINVAL;          if (!dentry || !mnt || !newname || newname_len <= 0) return -EINVAL;
         if (!current->fs) {  
                 printk("%s: current->fs == NULL for pid=%d\n", __FUNCTION__, current->pid);  
                 return -ENOENT;  
         }  
168          d_dentry = dget(dentry);          d_dentry = dget(dentry);
169          d_mnt = mntget(mnt);          d_mnt = mntget(mnt);
170          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
# Line 197  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 208  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 237  unsigned int GetMemoryUsedForElements(vo Line 241  unsigned int GetMemoryUsedForElements(vo
241  }  }
242    
243  /* Allocate memory for structures. The RAM is chunked, so NEVER try to kfree() the returned pointer. */  /* Allocate memory for structures. The RAM is chunked, so NEVER try to kfree() the returned pointer. */
244  char *alloc_element(const unsigned int size)  void *alloc_element(const unsigned int size)
245  {  {
246          static DECLARE_MUTEX(lock);          static DEFINE_MUTEX(lock);
247          static char *buf = NULL;          static char *buf = NULL;
248          static unsigned int buf_used_len = PAGE_SIZE;          static unsigned int buf_used_len = PAGE_SIZE;
249          char *ptr = NULL;          char *ptr = NULL;
250          const unsigned int word_aligned_size = ROUNDUP(size);          const unsigned int word_aligned_size = ROUNDUP(size);
251          if (word_aligned_size > PAGE_SIZE) return NULL;          if (word_aligned_size > PAGE_SIZE) return NULL;
252          down(&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 = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) {
255                          printk("ERROR: Out of memory for alloc_element().\n");                          printk("ERROR: Out of memory for alloc_element().\n");
# Line 268  char *alloc_element(const unsigned int s Line 272  char *alloc_element(const unsigned int s
272                          }                          }
273                  }                  }
274          }          }
275          up(&lock);          mutex_unlock(&lock);
276          return ptr;          return ptr;
277  }  }
278    
# Line 283  unsigned int GetMemoryUsedForSaveName(vo Line 287  unsigned int GetMemoryUsedForSaveName(vo
287    
288  #define MAX_HASH 256  #define MAX_HASH 256
289    
290  typedef 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  } NAME_ENTRY;  };
294    
295  typedef 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  } FREE_MEMORY_BLOCK_LIST;  };
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 FREE_MEMORY_BLOCK_LIST fmb_list = { NULL, NULL, 0 };          static LIST_HEAD(fmb_list);
307          static NAME_ENTRY name_list[MAX_HASH]; /* The list of names. */          static DEFINE_MUTEX(lock);
308          static DECLARE_MUTEX(lock);          struct name_entry *ptr;
         NAME_ENTRY *ptr, *prev = NULL;  
309          unsigned int hash;          unsigned int hash;
310          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 312  const struct path_info *SaveName(const c Line 317  const struct path_info *SaveName(const c
317                  return NULL;                  return NULL;
318          }          }
319          hash = full_name_hash((const unsigned char *) name, len - 1);          hash = full_name_hash((const unsigned char *) name, len - 1);
320          down(&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 = (FREE_MEMORY_BLOCK_LIST *) alloc_element(sizeof(FREE_MEMORY_BLOCK_LIST))) == 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 = (NAME_ENTRY *) alloc_element(sizeof(NAME_ENTRY))) == NULL) goto out;          cp = kmalloc(PAGE_SIZE, GFP_KERNEL);
328            fmb = kmalloc(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            memset(cp, 0, PAGE_SIZE);
338            allocated_memory_for_savename += PAGE_SIZE;
339            list_add(&fmb->list, &fmb_list);
340            fmb->ptr = cp;
341            fmb->len = PAGE_SIZE;
342     ready:
343            ptr = alloc_element(sizeof(*ptr));
344            if (!ptr) goto out;
345          ptr->entry.name = fmb->ptr;          ptr->entry.name = fmb->ptr;
346          memmove(fmb->ptr, name, len);          memmove(fmb->ptr, name, len);
347          fill_path_info(&ptr->entry);          fill_path_info(&ptr->entry);
348          fmb->ptr += len;          fmb->ptr += len;
349          fmb->len -= len;          fmb->len -= len;
350          prev->next = ptr; /* prev != NULL because name_list is not empty. */          list1_add_tail_mb(&ptr->list, &name_list[hash % MAX_HASH]);
351          if (fmb->len == 0) {          if (fmb->len == 0) {
352                  FREE_MEMORY_BLOCK_LIST *ptr = &fmb_list;                  list_del(&fmb->list);
353                  while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next;                  kfree(fmb);
354          }          }
355   out:   out:
356          up(&lock);          mutex_unlock(&lock);
357          return ptr ? &ptr->entry : NULL;          return ptr ? &ptr->entry : NULL;
358  }  }
359    
360  /***** Dynamic memory allocator. *****/  /***** Dynamic memory allocator. *****/
361    
362  typedef struct cache_entry {  struct cache_entry {
363          struct list_head list;          struct list_head list;
364          void *ptr;          void *ptr;
365          int size;          int size;
366  } CACHE_ENTRY;  };
367    
368  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
369  static struct kmem_cache *ccs_cachep = NULL;  static struct kmem_cache *ccs_cachep = NULL;
# Line 378  static kmem_cache_t *ccs_cachep = NULL; Line 373  static kmem_cache_t *ccs_cachep = NULL;
373    
374  void __init realpath_Init(void)  void __init realpath_Init(void)
375  {  {
376          ccs_cachep = kmem_cache_create("ccs_cache", sizeof(CACHE_ENTRY), 0, 0, NULL, NULL);          int i;
377    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
378            ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL);
379    #else
380            ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL);
381    #endif
382          if (!ccs_cachep) panic("Can't create cache.\n");          if (!ccs_cachep) panic("Can't create cache.\n");
383            for (i = 0; i < MAX_HASH; i++) {
384                    INIT_LIST1_HEAD(&name_list[i]);
385            }
386            if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) panic("Bad size.");
387            INIT_LIST1_HEAD(&KERNEL_DOMAIN.acl_info_list);
388            KERNEL_DOMAIN.domainname = SaveName(ROOT_NAME);
389            list1_add_tail_mb(&KERNEL_DOMAIN.list, &domain_list);
390            if (FindDomain(ROOT_NAME) != &KERNEL_DOMAIN) panic("Can't register KERNEL_DOMAIN");
391  }  }
392    
393  static LIST_HEAD(cache_list);  static LIST_HEAD(cache_list);
# Line 391  unsigned int GetMemoryUsedForDynamic(voi Line 399  unsigned int GetMemoryUsedForDynamic(voi
399          return dynamic_memory_size;          return dynamic_memory_size;
400  }  }
401    
402  char *ccs_alloc(const size_t size)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
403    static int round2(size_t size)
404    {
405    #if PAGE_SIZE == 4096
406            size_t bsize = 32;
407    #else
408            size_t bsize = 64;
409    #endif
410            while (size > bsize) bsize <<= 1;
411            return bsize;
412    }
413    #endif
414    
415    void *ccs_alloc(const size_t size)
416  {  {
417          void *ret = kmalloc(size, GFP_KERNEL);          void *ret = kmalloc(size, GFP_KERNEL);
418          if (ret) {          if (ret) {
419                  CACHE_ENTRY *new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL);                  struct cache_entry *new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL);
420                  if (!new_entry) {                  if (!new_entry) {
421                          kfree(ret); ret = NULL;                          kfree(ret); ret = NULL;
422                  } else {                  } else {
423                          INIT_LIST_HEAD(&new_entry->list);                          INIT_LIST_HEAD(&new_entry->list);
424                          new_entry->ptr = ret;                          new_entry->ptr = ret;
425                          new_entry->size = size;  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
426                            new_entry->size = ksize(ret);
427    #else
428                            new_entry->size = round2(size);
429    #endif
430                          spin_lock(&cache_list_lock);                          spin_lock(&cache_list_lock);
431                          list_add_tail(&new_entry->list, &cache_list);                          list_add_tail(&new_entry->list, &cache_list);
432                          dynamic_memory_size += size;                          dynamic_memory_size += new_entry->size;
433                          spin_unlock(&cache_list_lock);                          spin_unlock(&cache_list_lock);
434                          memset(ret, 0, size);                          memset(ret, 0, size);
435                  }                  }
436          }          }
437          return (char *) ret;          return ret;
438  }  }
439    
440  void ccs_free(const void *p)  void ccs_free(const void *p)
441  {  {
442          struct list_head *v;          struct list_head *v;
443          CACHE_ENTRY *entry = NULL;          struct cache_entry *entry = NULL;
444          if (!p) return;          if (!p) return;
445          spin_lock(&cache_list_lock);          spin_lock(&cache_list_lock);
446          list_for_each(v, &cache_list) {          list_for_each(v, &cache_list) {
447                  entry = list_entry(v, CACHE_ENTRY, list);                  entry = list_entry(v, struct cache_entry, list);
448                  if (entry->ptr != p) {                  if (entry->ptr != p) {
449                          entry = NULL; continue;                          entry = NULL; continue;
450                  }                  }

Legend:
Removed from v.111  
changed lines
  Added in v.1015

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