The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/ext3/ioctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * linux/fs/ext3/ioctl.c
    3  *
    4  * Copyright (C) 1993, 1994, 1995
    5  * Remy Card (card@masi.ibp.fr)
    6  * Laboratoire MASI - Institut Blaise Pascal
    7  * Universite Pierre et Marie Curie (Paris VI)
    8  */
    9 
   10 #include <linux/fs.h>
   11 #include <linux/jbd.h>
   12 #include <linux/ext3_fs.h>
   13 #include <linux/ext3_jbd.h>
   14 #include <linux/sched.h>
   15 #include <asm/uaccess.h>
   16 
   17 
   18 int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
   19                 unsigned long arg)
   20 {
   21         unsigned int flags;
   22 
   23         ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
   24 
   25         switch (cmd) {
   26         case EXT3_IOC_GETFLAGS:
   27                 flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE;
   28                 return put_user(flags, (int *) arg);
   29         case EXT3_IOC_SETFLAGS: {
   30                 handle_t *handle = NULL;
   31                 int err;
   32                 struct ext3_iloc iloc;
   33                 unsigned int oldflags;
   34                 unsigned int jflag;
   35 
   36                 if (IS_RDONLY(inode))
   37                         return -EROFS;
   38 
   39                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
   40                         return -EACCES;
   41 
   42                 if (get_user(flags, (int *) arg))
   43                         return -EFAULT;
   44 
   45                 oldflags = inode->u.ext3_i.i_flags;
   46 
   47                 /* The JOURNAL_DATA flag is modifiable only by root */
   48                 jflag = flags & EXT3_JOURNAL_DATA_FL;
   49 
   50                 /*
   51                  * The IMMUTABLE and APPEND_ONLY flags can only be changed by
   52                  * the relevant capability.
   53                  *
   54                  * This test looks nicer. Thanks to Pauline Middelink
   55                  */
   56                 if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
   57                         if (!capable(CAP_LINUX_IMMUTABLE))
   58                                 return -EPERM;
   59                 }
   60                 
   61                 /*
   62                  * The JOURNAL_DATA flag can only be changed by
   63                  * the relevant capability.
   64                  */
   65                 if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) {
   66                         if (!capable(CAP_SYS_RESOURCE))
   67                                 return -EPERM;
   68                 }
   69 
   70 
   71                 handle = ext3_journal_start(inode, 1);
   72                 if (IS_ERR(handle))
   73                         return PTR_ERR(handle);
   74                 if (IS_SYNC(inode))
   75                         handle->h_sync = 1;
   76                 err = ext3_reserve_inode_write(handle, inode, &iloc);
   77                 if (err)
   78                         goto flags_err;
   79                 
   80                 flags = flags & EXT3_FL_USER_MODIFIABLE;
   81                 flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
   82                 inode->u.ext3_i.i_flags = flags;
   83 
   84                 ext3_set_inode_flags(inode);
   85                 inode->i_ctime = CURRENT_TIME;
   86 
   87                 err = ext3_mark_iloc_dirty(handle, inode, &iloc);
   88 flags_err:
   89                 ext3_journal_stop(handle, inode);
   90                 if (err)
   91                         return err;
   92                 
   93                 if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
   94                         err = ext3_change_inode_journal_flag(inode, jflag);
   95                 return err;
   96         }
   97         case EXT3_IOC_GETVERSION:
   98         case EXT3_IOC_GETVERSION_OLD:
   99                 return put_user(inode->i_generation, (int *) arg);
  100         case EXT3_IOC_SETVERSION:
  101         case EXT3_IOC_SETVERSION_OLD: {
  102                 handle_t *handle;
  103                 struct ext3_iloc iloc;
  104                 __u32 generation;
  105                 int err;
  106 
  107                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
  108                         return -EPERM;
  109                 if (IS_RDONLY(inode))
  110                         return -EROFS;
  111                 if (get_user(generation, (int *) arg))
  112                         return -EFAULT;
  113 
  114                 handle = ext3_journal_start(inode, 1);
  115                 if (IS_ERR(handle))
  116                         return PTR_ERR(handle);
  117                 err = ext3_reserve_inode_write(handle, inode, &iloc);
  118                 if (err)
  119                         return err;
  120 
  121                 inode->i_ctime = CURRENT_TIME;
  122                 inode->i_generation = generation;
  123 
  124                 err = ext3_mark_iloc_dirty(handle, inode, &iloc);
  125                 ext3_journal_stop(handle, inode);
  126                 return err;
  127         }
  128 #ifdef CONFIG_JBD_DEBUG
  129         case EXT3_IOC_WAIT_FOR_READONLY:
  130                 /*
  131                  * This is racy - by the time we're woken up and running,
  132                  * the superblock could be released.  And the module could
  133                  * have been unloaded.  So sue me.
  134                  *
  135                  * Returns 1 if it slept, else zero.
  136                  */
  137                 {
  138                         struct super_block *sb = inode->i_sb;
  139                         DECLARE_WAITQUEUE(wait, current);
  140                         int ret = 0;
  141 
  142                         set_current_state(TASK_INTERRUPTIBLE);
  143                         add_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
  144                         if (timer_pending(&sb->u.ext3_sb.turn_ro_timer)) {
  145                                 schedule();
  146                                 ret = 1;
  147                         }
  148                         remove_wait_queue(&sb->u.ext3_sb.ro_wait_queue, &wait);
  149                         return ret;
  150                 }
  151 #endif
  152         default:
  153                 return -ENOTTY;
  154         }
  155 }

Cache object: 228a0c8018beca062ab1c861113b9ba6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.