LTP GCOV extension - code coverage report
Current view: directory - fs - filesystems.c
Test: 2.6.14_rebootonly_gcov.info
Date: 2006-05-22 Instrumented lines: 110
Code covered: 36.4 % Executed lines: 40

       1                 : /*
       2                 :  *  linux/fs/filesystems.c
       3                 :  *
       4                 :  *  Copyright (C) 1991, 1992  Linus Torvalds
       5                 :  *
       6                 :  *  table of configured filesystems
       7                 :  */
       8                 : 
       9                 : #include <linux/syscalls.h>
      10                 : #include <linux/fs.h>
      11                 : #include <linux/slab.h>
      12                 : #include <linux/kmod.h>
      13                 : #include <linux/init.h>
      14                 : #include <linux/module.h>
      15                 : #include <asm/uaccess.h>
      16                 : 
      17                 : /*
      18                 :  * Handling of filesystem drivers list.
      19                 :  * Rules:
      20                 :  *      Inclusion to/removals from/scanning of list are protected by spinlock.
      21                 :  *      During the unload module must call unregister_filesystem().
      22                 :  *      We can access the fields of list element if:
      23                 :  *              1) spinlock is held or
      24                 :  *              2) we hold the reference to the module.
      25                 :  *      The latter can be guaranteed by call of try_module_get(); if it
      26                 :  *      returned 0 we must skip the element, otherwise we got the reference.
      27                 :  *      Once the reference is obtained we can drop the spinlock.
      28                 :  */
      29                 : 
      30                 : static struct file_system_type *file_systems;
      31                 : static DEFINE_RWLOCK(file_systems_lock);
      32                 : 
      33                 : /* WARNING: This can be used only if we _already_ own a reference */
      34                 : void get_filesystem(struct file_system_type *fs)
      35              20 : {
      36              20 :         __module_get(fs->owner);
      37                 : }
      38                 : 
      39                 : void put_filesystem(struct file_system_type *fs)
      40              26 : {
      41              26 :         module_put(fs->owner);
      42                 : }
      43                 : 
      44                 : static struct file_system_type **find_filesystem(const char *name)
      45              53 : {
      46              53 :         struct file_system_type **p;
      47             644 :         for (p=&file_systems; *p; p=&(*p)->next)
      48             617 :                 if (strcmp((*p)->name,name) == 0)
      49             591 :                         break;
      50              53 :         return p;
      51                 : }
      52                 : 
      53                 : /**
      54                 :  *      register_filesystem - register a new filesystem
      55                 :  *      @fs: the file system structure
      56                 :  *
      57                 :  *      Adds the file system passed to the list of file systems the kernel
      58                 :  *      is aware of for mount and other syscalls. Returns 0 on success,
      59                 :  *      or a negative errno code on an error.
      60                 :  *
      61                 :  *      The &struct file_system_type that is passed is linked into the kernel 
      62                 :  *      structures and must not be freed until the file system has been
      63                 :  *      unregistered.
      64                 :  */
      65                 :  
      66                 : int register_filesystem(struct file_system_type * fs)
      67              27 : {
      68              27 :         int res = 0;
      69              27 :         struct file_system_type ** p;
      70                 : 
      71              27 :         if (!fs)
      72               0 :                 return -EINVAL;
      73              27 :         if (fs->next)
      74               0 :                 return -EBUSY;
      75              27 :         INIT_LIST_HEAD(&fs->fs_supers);
      76              27 :         write_lock(&file_systems_lock);
      77              27 :         p = find_filesystem(fs->name);
      78              27 :         if (*p)
      79               0 :                 res = -EBUSY;
      80                 :         else
      81              27 :                 *p = fs;
      82              27 :         write_unlock(&file_systems_lock);
      83              27 :         return res;
      84                 : }
      85                 : 
      86                 : EXPORT_SYMBOL(register_filesystem);
      87                 : 
      88                 : /**
      89                 :  *      unregister_filesystem - unregister a file system
      90                 :  *      @fs: filesystem to unregister
      91                 :  *
      92                 :  *      Remove a file system that was previously successfully registered
      93                 :  *      with the kernel. An error is returned if the file system is not found.
      94                 :  *      Zero is returned on a success.
      95                 :  *      
      96                 :  *      Once this function has returned the &struct file_system_type structure
      97                 :  *      may be freed or reused.
      98                 :  */
      99                 :  
     100                 : int unregister_filesystem(struct file_system_type * fs)
     101               0 : {
     102               0 :         struct file_system_type ** tmp;
     103                 : 
     104               0 :         write_lock(&file_systems_lock);
     105               0 :         tmp = &file_systems;
     106               0 :         while (*tmp) {
     107               0 :                 if (fs == *tmp) {
     108               0 :                         *tmp = fs->next;
     109               0 :                         fs->next = NULL;
     110               0 :                         write_unlock(&file_systems_lock);
     111               0 :                         return 0;
     112                 :                 }
     113               0 :                 tmp = &(*tmp)->next;
     114                 :         }
     115               0 :         write_unlock(&file_systems_lock);
     116               0 :         return -EINVAL;
     117                 : }
     118                 : 
     119                 : EXPORT_SYMBOL(unregister_filesystem);
     120                 : 
     121                 : static int fs_index(const char __user * __name)
     122               0 : {
     123               0 :         struct file_system_type * tmp;
     124               0 :         char * name;
     125               0 :         int err, index;
     126                 : 
     127               0 :         name = getname(__name);
     128               0 :         err = PTR_ERR(name);
     129               0 :         if (IS_ERR(name))
     130               0 :                 return err;
     131                 : 
     132               0 :         err = -EINVAL;
     133               0 :         read_lock(&file_systems_lock);
     134               0 :         for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
     135               0 :                 if (strcmp(tmp->name,name) == 0) {
     136               0 :                         err = index;
     137               0 :                         break;
     138                 :                 }
     139                 :         }
     140               0 :         read_unlock(&file_systems_lock);
     141               0 :         putname(name);
     142               0 :         return err;
     143                 : }
     144                 : 
     145                 : static int fs_name(unsigned int index, char __user * buf)
     146               0 : {
     147               0 :         struct file_system_type * tmp;
     148               0 :         int len, res;
     149                 : 
     150               0 :         read_lock(&file_systems_lock);
     151               0 :         for (tmp = file_systems; tmp; tmp = tmp->next, index--)
     152               0 :                 if (index <= 0 && try_module_get(tmp->owner))
     153               0 :                         break;
     154               0 :         read_unlock(&file_systems_lock);
     155               0 :         if (!tmp)
     156               0 :                 return -EINVAL;
     157                 : 
     158                 :         /* OK, we got the reference, so we can safely block */
     159               0 :         len = strlen(tmp->name) + 1;
     160               0 :         res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
     161               0 :         put_filesystem(tmp);
     162               0 :         return res;
     163                 : }
     164                 : 
     165                 : static int fs_maxindex(void)
     166               0 : {
     167               0 :         struct file_system_type * tmp;
     168               0 :         int index;
     169                 : 
     170               0 :         read_lock(&file_systems_lock);
     171               0 :         for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
     172                 :                 ;
     173               0 :         read_unlock(&file_systems_lock);
     174               0 :         return index;
     175                 : }
     176                 : 
     177                 : /*
     178                 :  * Whee.. Weird sysv syscall. 
     179                 :  */
     180                 : asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2)
     181               0 : {
     182               0 :         int retval = -EINVAL;
     183                 : 
     184               0 :         switch (option) {
     185                 :                 case 1:
     186               0 :                         retval = fs_index((const char __user *) arg1);
     187               0 :                         break;
     188                 : 
     189                 :                 case 2:
     190               0 :                         retval = fs_name(arg1, (char __user *) arg2);
     191               0 :                         break;
     192                 : 
     193                 :                 case 3:
     194               0 :                         retval = fs_maxindex();
     195               0 :                         break;
     196                 :         }
     197               0 :         return retval;
     198                 : }
     199                 : 
     200                 : int get_filesystem_list(char * buf)
     201               5 : {
     202               5 :         int len = 0;
     203               5 :         struct file_system_type * tmp;
     204                 : 
     205               5 :         read_lock(&file_systems_lock);
     206               5 :         tmp = file_systems;
     207               5 :         while (tmp && len < PAGE_SIZE - 80) {
     208             135 :                 len += sprintf(buf+len, "%s\t%s\n",
     209                 :                         (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
     210                 :                         tmp->name);
     211             135 :                 tmp = tmp->next;
     212                 :         }
     213               5 :         read_unlock(&file_systems_lock);
     214               5 :         return len;
     215                 : }
     216                 : 
     217                 : struct file_system_type *get_fs_type(const char *name)
     218              26 : {
     219              26 :         struct file_system_type *fs;
     220                 : 
     221              26 :         read_lock(&file_systems_lock);
     222              26 :         fs = *(find_filesystem(name));
     223              26 :         if (fs && !try_module_get(fs->owner))
     224               0 :                 fs = NULL;
     225              26 :         read_unlock(&file_systems_lock);
     226              26 :         if (!fs && (request_module("%s", name) == 0)) {
     227               0 :                 read_lock(&file_systems_lock);
     228               0 :                 fs = *(find_filesystem(name));
     229               0 :                 if (fs && !try_module_get(fs->owner))
     230               0 :                         fs = NULL;
     231               0 :                 read_unlock(&file_systems_lock);
     232                 :         }
     233              26 :         return fs;
     234                 : }
     235                 : 
     236                 : EXPORT_SYMBOL(get_fs_type);

Generated by: LTP GCOV extension version 1.4