aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 11:17:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 11:17:51 -0400
commitf16a5e347835c6a0ba958535cf6e6c89d50463b8 (patch)
tree41d2e7784f57212a3f910690e00dcd1707a7e47f /fs
parent110b93842e36b17598cf24874e90d0401431cda2 (diff)
parent7df0e0397b9a18358573274db9fdab991941062f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes: GFS2: Fix permissions checking for setflags ioctl() GFS2: Don't "get" xattrs for ACLs when ACLs are turned off GFS2: Rework reclaiming unlinked dinodes
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/acl.c4
-rw-r--r--fs/gfs2/file.c7
-rw-r--r--fs/gfs2/inode.c54
-rw-r--r--fs/gfs2/inode.h3
-rw-r--r--fs/gfs2/log.c2
-rw-r--r--fs/gfs2/log.h29
-rw-r--r--fs/gfs2/rgrp.c20
7 files changed, 65 insertions, 54 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 9fb76b0a0485..48171f4c943d 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -236,10 +236,14 @@ static int gfs2_xattr_system_get(struct dentry *dentry, const char *name,
236 void *buffer, size_t size, int xtype) 236 void *buffer, size_t size, int xtype)
237{ 237{
238 struct inode *inode = dentry->d_inode; 238 struct inode *inode = dentry->d_inode;
239 struct gfs2_sbd *sdp = GFS2_SB(inode);
239 struct posix_acl *acl; 240 struct posix_acl *acl;
240 int type; 241 int type;
241 int error; 242 int error;
242 243
244 if (!sdp->sd_args.ar_posix_acl)
245 return -EOPNOTSUPP;
246
243 type = gfs2_acl_type(name); 247 type = gfs2_acl_type(name);
244 if (type < 0) 248 if (type < 0)
245 return type; 249 return type;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index e6dd2aec6f82..b20bfcc9fa2d 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -218,6 +218,11 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
218 if (error) 218 if (error)
219 goto out_drop_write; 219 goto out_drop_write;
220 220
221 error = -EACCES;
222 if (!is_owner_or_cap(inode))
223 goto out;
224
225 error = 0;
221 flags = ip->i_diskflags; 226 flags = ip->i_diskflags;
222 new_flags = (flags & ~mask) | (reqflags & mask); 227 new_flags = (flags & ~mask) | (reqflags & mask);
223 if ((new_flags ^ flags) == 0) 228 if ((new_flags ^ flags) == 0)
@@ -275,8 +280,10 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
275{ 280{
276 struct inode *inode = filp->f_path.dentry->d_inode; 281 struct inode *inode = filp->f_path.dentry->d_inode;
277 u32 fsflags, gfsflags; 282 u32 fsflags, gfsflags;
283
278 if (get_user(fsflags, ptr)) 284 if (get_user(fsflags, ptr))
279 return -EFAULT; 285 return -EFAULT;
286
280 gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); 287 gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
281 if (!S_ISDIR(inode->i_mode)) { 288 if (!S_ISDIR(inode->i_mode)) {
282 if (gfsflags & GFS2_DIF_INHERIT_JDATA) 289 if (gfsflags & GFS2_DIF_INHERIT_JDATA)
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 51d8061fa07a..b5612cbb62a5 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -242,34 +242,38 @@ fail:
242} 242}
243 243
244/** 244/**
245 * gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation 245 * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation
246 * and try to reclaim it by doing iput.
247 *
248 * This function assumes no rgrp locks are currently held.
249 *
246 * @sb: The super block 250 * @sb: The super block
247 * no_addr: The inode number 251 * no_addr: The inode number
248 * @@inode: A pointer to the inode found, if any
249 * 252 *
250 * Returns: 0 and *inode if no errors occurred. If an error occurs,
251 * the resulting *inode may or may not be NULL.
252 */ 253 */
253 254
254int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, 255void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
255 struct inode **inode)
256{ 256{
257 struct gfs2_sbd *sdp; 257 struct gfs2_sbd *sdp;
258 struct gfs2_inode *ip; 258 struct gfs2_inode *ip;
259 struct gfs2_glock *io_gl; 259 struct gfs2_glock *io_gl;
260 int error; 260 int error;
261 struct gfs2_holder gh; 261 struct gfs2_holder gh;
262 struct inode *inode;
262 263
263 *inode = gfs2_iget_skip(sb, no_addr); 264 inode = gfs2_iget_skip(sb, no_addr);
264 265
265 if (!(*inode)) 266 if (!inode)
266 return -ENOBUFS; 267 return;
267 268
268 if (!((*inode)->i_state & I_NEW)) 269 /* If it's not a new inode, someone's using it, so leave it alone. */
269 return -ENOBUFS; 270 if (!(inode->i_state & I_NEW)) {
271 iput(inode);
272 return;
273 }
270 274
271 ip = GFS2_I(*inode); 275 ip = GFS2_I(inode);
272 sdp = GFS2_SB(*inode); 276 sdp = GFS2_SB(inode);
273 ip->i_no_formal_ino = -1; 277 ip->i_no_formal_ino = -1;
274 278
275 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); 279 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
@@ -284,15 +288,13 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
284 set_bit(GIF_INVALID, &ip->i_flags); 288 set_bit(GIF_INVALID, &ip->i_flags);
285 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, 289 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT,
286 &ip->i_iopen_gh); 290 &ip->i_iopen_gh);
287 if (unlikely(error)) { 291 if (unlikely(error))
288 if (error == GLR_TRYFAILED)
289 error = 0;
290 goto fail_iopen; 292 goto fail_iopen;
291 } 293
292 ip->i_iopen_gh.gh_gl->gl_object = ip; 294 ip->i_iopen_gh.gh_gl->gl_object = ip;
293 gfs2_glock_put(io_gl); 295 gfs2_glock_put(io_gl);
294 296
295 (*inode)->i_mode = DT2IF(DT_UNKNOWN); 297 inode->i_mode = DT2IF(DT_UNKNOWN);
296 298
297 /* 299 /*
298 * We must read the inode in order to work out its type in 300 * We must read the inode in order to work out its type in
@@ -303,16 +305,17 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
303 */ 305 */
304 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, 306 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
305 &gh); 307 &gh);
306 if (unlikely(error)) { 308 if (unlikely(error))
307 if (error == GLR_TRYFAILED)
308 error = 0;
309 goto fail_glock; 309 goto fail_glock;
310 } 310
311 /* Inode is now uptodate */ 311 /* Inode is now uptodate */
312 gfs2_glock_dq_uninit(&gh); 312 gfs2_glock_dq_uninit(&gh);
313 gfs2_set_iop(*inode); 313 gfs2_set_iop(inode);
314
315 /* The iput will cause it to be deleted. */
316 iput(inode);
317 return;
314 318
315 return 0;
316fail_glock: 319fail_glock:
317 gfs2_glock_dq(&ip->i_iopen_gh); 320 gfs2_glock_dq(&ip->i_iopen_gh);
318fail_iopen: 321fail_iopen:
@@ -321,7 +324,8 @@ fail_put:
321 ip->i_gl->gl_object = NULL; 324 ip->i_gl->gl_object = NULL;
322 gfs2_glock_put(ip->i_gl); 325 gfs2_glock_put(ip->i_gl);
323fail: 326fail:
324 return error; 327 iget_failed(inode);
328 return;
325} 329}
326 330
327static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) 331static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index e161461d4c57..300ada3f21de 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -84,8 +84,7 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip,
84extern void gfs2_set_iop(struct inode *inode); 84extern void gfs2_set_iop(struct inode *inode);
85extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, 85extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
86 u64 no_addr, u64 no_formal_ino); 86 u64 no_addr, u64 no_formal_ino);
87extern int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, 87extern void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr);
88 struct inode **inode);
89extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); 88extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
90 89
91extern int gfs2_inode_refresh(struct gfs2_inode *ip); 90extern int gfs2_inode_refresh(struct gfs2_inode *ip);
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index b593f0e28f25..6a857e24f947 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -696,7 +696,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
696 * 696 *
697 */ 697 */
698 698
699void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) 699void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
700{ 700{
701 struct gfs2_ail *ai; 701 struct gfs2_ail *ai;
702 702
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index eb570b4ad443..0d007f920234 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -47,28 +47,21 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp,
47 sdp->sd_log_head = sdp->sd_log_tail = value; 47 sdp->sd_log_head = sdp->sd_log_tail = value;
48} 48}
49 49
50unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, 50extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
51 unsigned int ssize); 51 unsigned int ssize);
52 52
53int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); 53extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
54void gfs2_log_incr_head(struct gfs2_sbd *sdp); 54extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
55 55
56struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); 56extern struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp);
57struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, 57extern struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
58 struct buffer_head *real); 58 struct buffer_head *real);
59void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); 59extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
60extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
61extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
60 62
61static inline void gfs2_log_flush(struct gfs2_sbd *sbd, struct gfs2_glock *gl) 63extern void gfs2_log_shutdown(struct gfs2_sbd *sdp);
62{ 64extern void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
63 if (!gl || test_bit(GLF_LFLUSH, &gl->gl_flags)) 65extern int gfs2_logd(void *data);
64 __gfs2_log_flush(sbd, gl);
65}
66
67void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
68void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
69
70void gfs2_log_shutdown(struct gfs2_sbd *sdp);
71void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
72int gfs2_logd(void *data);
73 66
74#endif /* __LOG_DOT_H__ */ 67#endif /* __LOG_DOT_H__ */
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 117fa4171f62..171a744f8e45 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1192,7 +1192,6 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1192{ 1192{
1193 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1193 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1194 struct gfs2_alloc *al = ip->i_alloc; 1194 struct gfs2_alloc *al = ip->i_alloc;
1195 struct inode *inode;
1196 int error = 0; 1195 int error = 0;
1197 u64 last_unlinked = NO_BLOCK, unlinked; 1196 u64 last_unlinked = NO_BLOCK, unlinked;
1198 1197
@@ -1210,22 +1209,27 @@ try_again:
1210 if (error) 1209 if (error)
1211 return error; 1210 return error;
1212 1211
1212 /* Find an rgrp suitable for allocation. If it encounters any unlinked
1213 dinodes along the way, error will equal -EAGAIN and unlinked will
1214 contains it block address. We then need to look up that inode and
1215 try to free it, and try the allocation again. */
1213 error = get_local_rgrp(ip, &unlinked, &last_unlinked); 1216 error = get_local_rgrp(ip, &unlinked, &last_unlinked);
1214 if (error) { 1217 if (error) {
1215 if (ip != GFS2_I(sdp->sd_rindex)) 1218 if (ip != GFS2_I(sdp->sd_rindex))
1216 gfs2_glock_dq_uninit(&al->al_ri_gh); 1219 gfs2_glock_dq_uninit(&al->al_ri_gh);
1217 if (error != -EAGAIN) 1220 if (error != -EAGAIN)
1218 return error; 1221 return error;
1219 error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb, 1222
1220 unlinked, &inode); 1223 gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked);
1221 if (inode) 1224 /* regardless of whether or not gfs2_process_unlinked_inode
1222 iput(inode); 1225 was successful, we don't want to repeat it again. */
1226 last_unlinked = unlinked;
1223 gfs2_log_flush(sdp, NULL); 1227 gfs2_log_flush(sdp, NULL);
1224 if (error == GLR_TRYFAILED) 1228 error = 0;
1225 error = 0; 1229
1226 goto try_again; 1230 goto try_again;
1227 } 1231 }
1228 1232 /* no error, so we have the rgrp set in the inode's allocation. */
1229 al->al_file = file; 1233 al->al_file = file;
1230 al->al_line = line; 1234 al->al_line = line;
1231 1235