aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/glock.c7
-rw-r--r--fs/gfs2/glops.c12
-rw-r--r--fs/gfs2/glops.h1
-rw-r--r--fs/gfs2/rgrp.c2
-rw-r--r--fs/gfs2/sys.c43
5 files changed, 61 insertions, 4 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index ad8e121427c0..3984e47d1d33 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -684,10 +684,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
684 gl = search_bucket(hash, sdp, &name); 684 gl = search_bucket(hash, sdp, &name);
685 read_unlock(gl_lock_addr(hash)); 685 read_unlock(gl_lock_addr(hash));
686 686
687 if (gl || !create) { 687 *glp = gl;
688 *glp = gl; 688 if (gl)
689 return 0; 689 return 0;
690 } 690 if (!create)
691 return -ENOENT;
691 692
692 gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL); 693 gl = kmem_cache_alloc(gfs2_glock_cachep, GFP_KERNEL);
693 if (!gl) 694 if (!gl)
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index a9b7d3a60081..f34bc7093dd1 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -447,3 +447,15 @@ const struct gfs2_glock_operations gfs2_journal_glops = {
447 .go_type = LM_TYPE_JOURNAL, 447 .go_type = LM_TYPE_JOURNAL,
448}; 448};
449 449
450const struct gfs2_glock_operations *gfs2_glops_list[] = {
451 [LM_TYPE_META] = &gfs2_meta_glops,
452 [LM_TYPE_INODE] = &gfs2_inode_glops,
453 [LM_TYPE_RGRP] = &gfs2_rgrp_glops,
454 [LM_TYPE_NONDISK] = &gfs2_trans_glops,
455 [LM_TYPE_IOPEN] = &gfs2_iopen_glops,
456 [LM_TYPE_FLOCK] = &gfs2_flock_glops,
457 [LM_TYPE_NONDISK] = &gfs2_nondisk_glops,
458 [LM_TYPE_QUOTA] = &gfs2_quota_glops,
459 [LM_TYPE_JOURNAL] = &gfs2_journal_glops,
460};
461
diff --git a/fs/gfs2/glops.h b/fs/gfs2/glops.h
index a1d9b5b024e6..b3aa2e3210fd 100644
--- a/fs/gfs2/glops.h
+++ b/fs/gfs2/glops.h
@@ -21,5 +21,6 @@ extern const struct gfs2_glock_operations gfs2_flock_glops;
21extern const struct gfs2_glock_operations gfs2_nondisk_glops; 21extern const struct gfs2_glock_operations gfs2_nondisk_glops;
22extern const struct gfs2_glock_operations gfs2_quota_glops; 22extern const struct gfs2_glock_operations gfs2_quota_glops;
23extern const struct gfs2_glock_operations gfs2_journal_glops; 23extern const struct gfs2_glock_operations gfs2_journal_glops;
24extern const struct gfs2_glock_operations *gfs2_glops_list[];
24 25
25#endif /* __GLOPS_DOT_H__ */ 26#endif /* __GLOPS_DOT_H__ */
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 789953a2b6a8..a068ac940de1 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -839,7 +839,7 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
839 const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / 839 const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize /
840 bdev_hardsect_size(sb->s_bdev); 840 bdev_hardsect_size(sb->s_bdev);
841 u64 blk; 841 u64 blk;
842 sector_t start; 842 sector_t start = 0;
843 sector_t nr_sects = 0; 843 sector_t nr_sects = 0;
844 int rv; 844 int rv;
845 unsigned int x; 845 unsigned int x;
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 4d284d14980b..7655f5025fec 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -24,6 +24,7 @@
24#include "glock.h" 24#include "glock.h"
25#include "quota.h" 25#include "quota.h"
26#include "util.h" 26#include "util.h"
27#include "glops.h"
27 28
28static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) 29static ssize_t id_show(struct gfs2_sbd *sdp, char *buf)
29{ 30{
@@ -171,6 +172,46 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
171 return len; 172 return len;
172} 173}
173 174
175static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
176{
177 struct gfs2_glock *gl;
178 const struct gfs2_glock_operations *glops;
179 unsigned int glmode;
180 unsigned int gltype;
181 unsigned long long glnum;
182 char mode[16];
183 int rv;
184
185 if (!capable(CAP_SYS_ADMIN))
186 return -EACCES;
187
188 rv = sscanf(buf, "%u:%llu %15s", &gltype, &glnum,
189 mode);
190 if (rv != 3)
191 return -EINVAL;
192
193 if (strcmp(mode, "EX") == 0)
194 glmode = LM_ST_UNLOCKED;
195 else if ((strcmp(mode, "CW") == 0) || (strcmp(mode, "DF") == 0))
196 glmode = LM_ST_DEFERRED;
197 else if ((strcmp(mode, "PR") == 0) || (strcmp(mode, "SH") == 0))
198 glmode = LM_ST_SHARED;
199 else
200 return -EINVAL;
201
202 if (gltype > LM_TYPE_JOURNAL)
203 return -EINVAL;
204 glops = gfs2_glops_list[gltype];
205 if (glops == NULL)
206 return -EINVAL;
207 rv = gfs2_glock_get(sdp, glnum, glops, 0, &gl);
208 if (rv)
209 return rv;
210 gfs2_glock_cb(gl, glmode);
211 gfs2_glock_put(gl);
212 return len;
213}
214
174struct gfs2_attr { 215struct gfs2_attr {
175 struct attribute attr; 216 struct attribute attr;
176 ssize_t (*show)(struct gfs2_sbd *, char *); 217 ssize_t (*show)(struct gfs2_sbd *, char *);
@@ -189,6 +230,7 @@ GFS2_ATTR(statfs_sync, 0200, NULL, statfs_sync_store);
189GFS2_ATTR(quota_sync, 0200, NULL, quota_sync_store); 230GFS2_ATTR(quota_sync, 0200, NULL, quota_sync_store);
190GFS2_ATTR(quota_refresh_user, 0200, NULL, quota_refresh_user_store); 231GFS2_ATTR(quota_refresh_user, 0200, NULL, quota_refresh_user_store);
191GFS2_ATTR(quota_refresh_group, 0200, NULL, quota_refresh_group_store); 232GFS2_ATTR(quota_refresh_group, 0200, NULL, quota_refresh_group_store);
233GFS2_ATTR(demote_rq, 0200, NULL, demote_rq_store);
192 234
193static struct attribute *gfs2_attrs[] = { 235static struct attribute *gfs2_attrs[] = {
194 &gfs2_attr_id.attr, 236 &gfs2_attr_id.attr,
@@ -200,6 +242,7 @@ static struct attribute *gfs2_attrs[] = {
200 &gfs2_attr_quota_sync.attr, 242 &gfs2_attr_quota_sync.attr,
201 &gfs2_attr_quota_refresh_user.attr, 243 &gfs2_attr_quota_refresh_user.attr,
202 &gfs2_attr_quota_refresh_group.attr, 244 &gfs2_attr_quota_refresh_group.attr,
245 &gfs2_attr_demote_rq.attr,
203 NULL, 246 NULL,
204}; 247};
205 248