Blame view

fs/gfs2/acl.c 3.12 KB
7336d0e65   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
b3b94faa5   David Teigland   [GFS2] The core o...
2
3
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
4
   * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
5
6
7
8
9
10
11
   */
  
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
2646a1f61   Steven Whitehouse   GFS2: Fix up syst...
12
  #include <linux/xattr.h>
b3b94faa5   David Teigland   [GFS2] The core o...
13
14
  #include <linux/posix_acl.h>
  #include <linux/posix_acl_xattr.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
15
  #include <linux/gfs2_ondisk.h>
b3b94faa5   David Teigland   [GFS2] The core o...
16
17
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
18
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
19
  #include "acl.h"
307cf6e63   Steven Whitehouse   GFS2: Rename eatt...
20
  #include "xattr.h"
b3b94faa5   David Teigland   [GFS2] The core o...
21
22
23
  #include "glock.h"
  #include "inode.h"
  #include "meta_io.h"
d580712a3   Bob Peterson   gfs2: eliminate g...
24
  #include "quota.h"
1a39ba99b   Al Viro   gfs2: Switch to g...
25
  #include "rgrp.h"
b3b94faa5   David Teigland   [GFS2] The core o...
26
  #include "trans.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
27
  #include "util.h"
b3b94faa5   David Teigland   [GFS2] The core o...
28

479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
29
  static const char *gfs2_acl_name(int type)
b3b94faa5   David Teigland   [GFS2] The core o...
30
  {
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
31
32
  	switch (type) {
  	case ACL_TYPE_ACCESS:
97d792992   Andreas Gruenbacher   posix acls: Remov...
33
  		return XATTR_POSIX_ACL_ACCESS;
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
34
  	case ACL_TYPE_DEFAULT:
97d792992   Andreas Gruenbacher   posix acls: Remov...
35
  		return XATTR_POSIX_ACL_DEFAULT;
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
36
37
38
  	}
  	return NULL;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
39

1a39ba99b   Al Viro   gfs2: Switch to g...
40
  static struct posix_acl *__gfs2_get_acl(struct inode *inode, int type)
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
41
  {
018a01cd2   Steven Whitehouse   GFS2: We only nee...
42
  	struct gfs2_inode *ip = GFS2_I(inode);
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
43
44
45
46
  	struct posix_acl *acl;
  	const char *name;
  	char *data;
  	int len;
40b78a322   Steven Whitehouse   GFS2: Clean up of...
47

3767ac21f   Steven Whitehouse   GFS2: Move di_eat...
48
  	if (!ip->i_eattr)
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
49
  		return NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
50

479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
51
  	name = gfs2_acl_name(type);
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
52
  	len = gfs2_xattr_acl_get(ip, name, &data);
1a39ba99b   Al Viro   gfs2: Switch to g...
53
  	if (len <= 0)
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
54
  		return ERR_PTR(len);
5f3a4a28e   Eric W. Biederman   userns: Pass a us...
55
  	acl = posix_acl_from_xattr(&init_user_ns, data, len);
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
56
57
  	kfree(data);
  	return acl;
b3b94faa5   David Teigland   [GFS2] The core o...
58
  }
1a39ba99b   Al Viro   gfs2: Switch to g...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  struct posix_acl *gfs2_get_acl(struct inode *inode, int type)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_holder gh;
  	bool need_unlock = false;
  	struct posix_acl *acl;
  
  	if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
  		int ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
  					     LM_FLAG_ANY, &gh);
  		if (ret)
  			return ERR_PTR(ret);
  		need_unlock = true;
  	}
  	acl = __gfs2_get_acl(inode, type);
  	if (need_unlock)
  		gfs2_glock_dq_uninit(&gh);
  	return acl;
  }
  
  int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
b3b94faa5   David Teigland   [GFS2] The core o...
80
  {
b3b94faa5   David Teigland   [GFS2] The core o...
81
  	int error;
910f3d58d   Chengguang Xu   gfs2: using posix...
82
  	size_t len;
479c427dd   Steven Whitehouse   GFS2: Clean up ACLs
83
84
  	char *data;
  	const char *name = gfs2_acl_name(type);
e01580bf9   Christoph Hellwig   gfs2: use generic...
85
  	if (acl) {
910f3d58d   Chengguang Xu   gfs2: using posix...
86
  		len = posix_acl_xattr_size(acl->a_count);
e01580bf9   Christoph Hellwig   gfs2: use generic...
87
88
89
90
91
92
93
94
95
  		data = kmalloc(len, GFP_NOFS);
  		if (data == NULL)
  			return -ENOMEM;
  		error = posix_acl_to_xattr(&init_user_ns, acl, data, len);
  		if (error < 0)
  			goto out;
  	} else {
  		data = NULL;
  		len = 0;
106381bfb   Steven Whitehouse   GFS2: Add cached ...
96
  	}
e01580bf9   Christoph Hellwig   gfs2: use generic...
97
98
99
100
  
  	error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);
  	if (error)
  		goto out;
932e468a3   Andreas Gruenbacher   GFS2: gfs2_set_ac...
101
  	set_cached_acl(inode, type, acl);
2646a1f61   Steven Whitehouse   GFS2: Fix up syst...
102
  out:
e01580bf9   Christoph Hellwig   gfs2: use generic...
103
  	kfree(data);
2646a1f61   Steven Whitehouse   GFS2: Fix up syst...
104
105
  	return error;
  }
1a39ba99b   Al Viro   gfs2: Switch to g...
106
107
108
109
110
111
112
  
  int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_holder gh;
  	bool need_unlock = false;
  	int ret;
309e8cda5   Ernesto A. Fernández   gfs2: preserve i_...
113
  	umode_t mode;
1a39ba99b   Al Viro   gfs2: Switch to g...
114

914cea93d   Jan Kara   gfs2: Don't clear...
115
116
  	if (acl && acl->a_count > GFS2_ACL_MAX_ENTRIES(GFS2_SB(inode)))
  		return -E2BIG;
2fba46a04   Bob Peterson   gfs2: Change inod...
117
  	ret = gfs2_qa_get(ip);
1a39ba99b   Al Viro   gfs2: Switch to g...
118
119
120
121
122
123
  	if (ret)
  		return ret;
  
  	if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
  		ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  		if (ret)
2fba46a04   Bob Peterson   gfs2: Change inod...
124
  			goto out;
1a39ba99b   Al Viro   gfs2: Switch to g...
125
126
  		need_unlock = true;
  	}
914cea93d   Jan Kara   gfs2: Don't clear...
127

309e8cda5   Ernesto A. Fernández   gfs2: preserve i_...
128
129
130
  	mode = inode->i_mode;
  	if (type == ACL_TYPE_ACCESS && acl) {
  		ret = posix_acl_update_mode(inode, &mode, &acl);
914cea93d   Jan Kara   gfs2: Don't clear...
131
132
  		if (ret)
  			goto unlock;
914cea93d   Jan Kara   gfs2: Don't clear...
133
  	}
1a39ba99b   Al Viro   gfs2: Switch to g...
134
  	ret = __gfs2_set_acl(inode, acl, type);
309e8cda5   Ernesto A. Fernández   gfs2: preserve i_...
135
  	if (!ret && mode != inode->i_mode) {
c2c4be28c   Andreas Gruenbacher   gfs2: Always upda...
136
  		inode->i_ctime = current_time(inode);
309e8cda5   Ernesto A. Fernández   gfs2: preserve i_...
137
138
139
  		inode->i_mode = mode;
  		mark_inode_dirty(inode);
  	}
914cea93d   Jan Kara   gfs2: Don't clear...
140
  unlock:
1a39ba99b   Al Viro   gfs2: Switch to g...
141
142
  	if (need_unlock)
  		gfs2_glock_dq_uninit(&gh);
2fba46a04   Bob Peterson   gfs2: Change inod...
143
144
  out:
  	gfs2_qa_put(ip);
1a39ba99b   Al Viro   gfs2: Switch to g...
145
146
  	return ret;
  }