Blame view

fs/jfs/ioctl.c 2.24 KB
d9e902668   Herbert Poetzl   JFS: Add missing ...
1
2
3
4
5
6
7
8
  /*
   * linux/fs/jfs/ioctl.c
   *
   * Copyright (C) 2006 Herbert Poetzl
   * adapted from Remy Card's ext2/ioctl.c
   */
  
  #include <linux/fs.h>
d9e902668   Herbert Poetzl   JFS: Add missing ...
9
10
11
  #include <linux/ctype.h>
  #include <linux/capability.h>
  #include <linux/time.h>
914e26379   Al Viro   [PATCH] severing ...
12
  #include <linux/sched.h>
d9e902668   Herbert Poetzl   JFS: Add missing ...
13
14
15
16
17
18
19
20
21
22
23
24
  #include <asm/current.h>
  #include <asm/uaccess.h>
  
  #include "jfs_incore.h"
  #include "jfs_dinode.h"
  #include "jfs_inode.h"
  
  
  static struct {
  	long jfs_flag;
  	long ext2_flag;
  } jfs_map[] = {
36695673b   David Howells   [PATCH] BLOCK: Mo...
25
26
27
28
29
30
31
  	{JFS_NOATIME_FL,	FS_NOATIME_FL},
  	{JFS_DIRSYNC_FL,	FS_DIRSYNC_FL},
  	{JFS_SYNC_FL,		FS_SYNC_FL},
  	{JFS_SECRM_FL,		FS_SECRM_FL},
  	{JFS_UNRM_FL,		FS_UNRM_FL},
  	{JFS_APPEND_FL,		FS_APPEND_FL},
  	{JFS_IMMUTABLE_FL,	FS_IMMUTABLE_FL},
d9e902668   Herbert Poetzl   JFS: Add missing ...
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  	{0, 0},
  };
  
  static long jfs_map_ext2(unsigned long flags, int from)
  {
  	int index=0;
  	long mapped=0;
  
  	while (jfs_map[index].jfs_flag) {
  		if (from) {
  			if (jfs_map[index].ext2_flag & flags)
  				mapped |= jfs_map[index].jfs_flag;
  		} else {
  			if (jfs_map[index].jfs_flag & flags)
  				mapped |= jfs_map[index].ext2_flag;
  		}
  		index++;
  	}
  	return mapped;
  }
  
  
  int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
  		unsigned long arg)
  {
  	struct jfs_inode_info *jfs_inode = JFS_IP(inode);
  	unsigned int flags;
  
  	switch (cmd) {
  	case JFS_IOC_GETFLAGS:
3e2221c73   Dave Kleikamp   Copy i_flags to j...
62
  		jfs_get_inode_flags(jfs_inode);
d9e902668   Herbert Poetzl   JFS: Add missing ...
63
64
65
66
67
68
69
70
  		flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
  		flags = jfs_map_ext2(flags, 0);
  		return put_user(flags, (int __user *) arg);
  	case JFS_IOC_SETFLAGS: {
  		unsigned int oldflags;
  
  		if (IS_RDONLY(inode))
  			return -EROFS;
3bd858ab1   Satyam Sharma   Introduce is_owne...
71
  		if (!is_owner_or_cap(inode))
d9e902668   Herbert Poetzl   JFS: Add missing ...
72
73
74
75
76
77
78
79
  			return -EACCES;
  
  		if (get_user(flags, (int __user *) arg))
  			return -EFAULT;
  
  		flags = jfs_map_ext2(flags, 1);
  		if (!S_ISDIR(inode->i_mode))
  			flags &= ~JFS_DIRSYNC_FL;
3e2221c73   Dave Kleikamp   Copy i_flags to j...
80
  		jfs_get_inode_flags(jfs_inode);
d9e902668   Herbert Poetzl   JFS: Add missing ...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  		oldflags = jfs_inode->mode2;
  
  		/*
  		 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
  		 * the relevant capability.
  		 */
  		if ((oldflags & JFS_IMMUTABLE_FL) ||
  			((flags ^ oldflags) &
  			(JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
  			if (!capable(CAP_LINUX_IMMUTABLE))
  				return -EPERM;
  		}
  
  		flags = flags & JFS_FL_USER_MODIFIABLE;
  		flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
  		jfs_inode->mode2 = flags;
  
  		jfs_set_inode_flags(inode);
  		inode->i_ctime = CURRENT_TIME_SEC;
  		mark_inode_dirty(inode);
  		return 0;
  	}
  	default:
  		return -ENOTTY;
  	}
  }