~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/hfsplus/ioctl.c

Version: ~ [ linux-5.16-rc3 ] ~ [ linux-5.15.5 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.82 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.162 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.218 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.256 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.291 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.293 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/fs/hfsplus/ioctl.c
  3  *
  4  * Copyright (C) 2003
  5  * Ethan Benson <erbenson@alaska.net>
  6  * partially derived from linux/fs/ext2/ioctl.c
  7  * Copyright (C) 1993, 1994, 1995
  8  * Remy Card (card@masi.ibp.fr)
  9  * Laboratoire MASI - Institut Blaise Pascal
 10  * Universite Pierre et Marie Curie (Paris VI)
 11  *
 12  * hfsplus ioctls
 13  */
 14 
 15 #include <linux/capability.h>
 16 #include <linux/fs.h>
 17 #include <linux/mount.h>
 18 #include <linux/sched.h>
 19 #include <asm/uaccess.h>
 20 #include "hfsplus_fs.h"
 21 
 22 /*
 23  * "Blessing" an HFS+ filesystem writes metadata to the superblock informing
 24  * the platform firmware which file to boot from
 25  */
 26 static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags)
 27 {
 28         struct dentry *dentry = file->f_path.dentry;
 29         struct inode *inode = dentry->d_inode;
 30         struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb);
 31         struct hfsplus_vh *vh = sbi->s_vhdr;
 32         struct hfsplus_vh *bvh = sbi->s_backup_vhdr;
 33         u32 cnid = (unsigned long)dentry->d_fsdata;
 34 
 35         if (!capable(CAP_SYS_ADMIN))
 36                 return -EPERM;
 37 
 38         mutex_lock(&sbi->vh_mutex);
 39 
 40         /* Directory containing the bootable system */
 41         vh->finder_info[0] = bvh->finder_info[0] =
 42                 cpu_to_be32(parent_ino(dentry));
 43 
 44         /*
 45          * Bootloader. Just using the inode here breaks in the case of
 46          * hard links - the firmware wants the ID of the hard link file,
 47          * but the inode points at the indirect inode
 48          */
 49         vh->finder_info[1] = bvh->finder_info[1] = cpu_to_be32(cnid);
 50 
 51         /* Per spec, the OS X system folder - same as finder_info[0] here */
 52         vh->finder_info[5] = bvh->finder_info[5] =
 53                 cpu_to_be32(parent_ino(dentry));
 54 
 55         mutex_unlock(&sbi->vh_mutex);
 56         return 0;
 57 }
 58 
 59 static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags)
 60 {
 61         struct inode *inode = file_inode(file);
 62         struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
 63         unsigned int flags = 0;
 64 
 65         if (inode->i_flags & S_IMMUTABLE)
 66                 flags |= FS_IMMUTABLE_FL;
 67         if (inode->i_flags & S_APPEND)
 68                 flags |= FS_APPEND_FL;
 69         if (hip->userflags & HFSPLUS_FLG_NODUMP)
 70                 flags |= FS_NODUMP_FL;
 71 
 72         return put_user(flags, user_flags);
 73 }
 74 
 75 static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags)
 76 {
 77         struct inode *inode = file_inode(file);
 78         struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
 79         unsigned int flags;
 80         int err = 0;
 81 
 82         err = mnt_want_write_file(file);
 83         if (err)
 84                 goto out;
 85 
 86         if (!inode_owner_or_capable(inode)) {
 87                 err = -EACCES;
 88                 goto out_drop_write;
 89         }
 90 
 91         if (get_user(flags, user_flags)) {
 92                 err = -EFAULT;
 93                 goto out_drop_write;
 94         }
 95 
 96         mutex_lock(&inode->i_mutex);
 97 
 98         if ((flags & (FS_IMMUTABLE_FL|FS_APPEND_FL)) ||
 99             inode->i_flags & (S_IMMUTABLE|S_APPEND)) {
100                 if (!capable(CAP_LINUX_IMMUTABLE)) {
101                         err = -EPERM;
102                         goto out_unlock_inode;
103                 }
104         }
105 
106         /* don't silently ignore unsupported ext2 flags */
107         if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) {
108                 err = -EOPNOTSUPP;
109                 goto out_unlock_inode;
110         }
111 
112         if (flags & FS_IMMUTABLE_FL)
113                 inode->i_flags |= S_IMMUTABLE;
114         else
115                 inode->i_flags &= ~S_IMMUTABLE;
116 
117         if (flags & FS_APPEND_FL)
118                 inode->i_flags |= S_APPEND;
119         else
120                 inode->i_flags &= ~S_APPEND;
121 
122         if (flags & FS_NODUMP_FL)
123                 hip->userflags |= HFSPLUS_FLG_NODUMP;
124         else
125                 hip->userflags &= ~HFSPLUS_FLG_NODUMP;
126 
127         inode->i_ctime = CURRENT_TIME_SEC;
128         mark_inode_dirty(inode);
129 
130 out_unlock_inode:
131         mutex_unlock(&inode->i_mutex);
132 out_drop_write:
133         mnt_drop_write_file(file);
134 out:
135         return err;
136 }
137 
138 long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
139 {
140         void __user *argp = (void __user *)arg;
141 
142         switch (cmd) {
143         case HFSPLUS_IOC_EXT2_GETFLAGS:
144                 return hfsplus_ioctl_getflags(file, argp);
145         case HFSPLUS_IOC_EXT2_SETFLAGS:
146                 return hfsplus_ioctl_setflags(file, argp);
147         case HFSPLUS_IOC_BLESS:
148                 return hfsplus_ioctl_bless(file, argp);
149         default:
150                 return -ENOTTY;
151         }
152 }
153 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp