Skip to content

Commit f16a5e3

Browse files
committed
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
2 parents 110b938 + 7df0e03 commit f16a5e3

File tree

7 files changed

+65
-54
lines changed

7 files changed

+65
-54
lines changed

fs/gfs2/acl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,14 @@ static int gfs2_xattr_system_get(struct dentry *dentry, const char *name,
236236
void *buffer, size_t size, int xtype)
237237
{
238238
struct inode *inode = dentry->d_inode;
239+
struct gfs2_sbd *sdp = GFS2_SB(inode);
239240
struct posix_acl *acl;
240241
int type;
241242
int error;
242243

244+
if (!sdp->sd_args.ar_posix_acl)
245+
return -EOPNOTSUPP;
246+
243247
type = gfs2_acl_type(name);
244248
if (type < 0)
245249
return type;

fs/gfs2/file.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
218218
if (error)
219219
goto out_drop_write;
220220

221+
error = -EACCES;
222+
if (!is_owner_or_cap(inode))
223+
goto out;
224+
225+
error = 0;
221226
flags = ip->i_diskflags;
222227
new_flags = (flags & ~mask) | (reqflags & mask);
223228
if ((new_flags ^ flags) == 0)
@@ -275,8 +280,10 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
275280
{
276281
struct inode *inode = filp->f_path.dentry->d_inode;
277282
u32 fsflags, gfsflags;
283+
278284
if (get_user(fsflags, ptr))
279285
return -EFAULT;
286+
280287
gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
281288
if (!S_ISDIR(inode->i_mode)) {
282289
if (gfsflags & GFS2_DIF_INHERIT_JDATA)

fs/gfs2/inode.c

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -242,34 +242,38 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
242242
}
243243

244244
/**
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+
*
246250
* @sb: The super block
247251
* no_addr: The inode number
248-
* @@inode: A pointer to the inode found, if any
249252
*
250-
* Returns: 0 and *inode if no errors occurred. If an error occurs,
251-
* the resulting *inode may or may not be NULL.
252253
*/
253254

254-
int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
255-
struct inode **inode)
255+
void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
256256
{
257257
struct gfs2_sbd *sdp;
258258
struct gfs2_inode *ip;
259259
struct gfs2_glock *io_gl;
260260
int error;
261261
struct gfs2_holder gh;
262+
struct inode *inode;
262263

263-
*inode = gfs2_iget_skip(sb, no_addr);
264+
inode = gfs2_iget_skip(sb, no_addr);
264265

265-
if (!(*inode))
266-
return -ENOBUFS;
266+
if (!inode)
267+
return;
267268

268-
if (!((*inode)->i_state & I_NEW))
269-
return -ENOBUFS;
269+
/* If it's not a new inode, someone's using it, so leave it alone. */
270+
if (!(inode->i_state & I_NEW)) {
271+
iput(inode);
272+
return;
273+
}
270274

271-
ip = GFS2_I(*inode);
272-
sdp = GFS2_SB(*inode);
275+
ip = GFS2_I(inode);
276+
sdp = GFS2_SB(inode);
273277
ip->i_no_formal_ino = -1;
274278

275279
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,
284288
set_bit(GIF_INVALID, &ip->i_flags);
285289
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT,
286290
&ip->i_iopen_gh);
287-
if (unlikely(error)) {
288-
if (error == GLR_TRYFAILED)
289-
error = 0;
291+
if (unlikely(error))
290292
goto fail_iopen;
291-
}
293+
292294
ip->i_iopen_gh.gh_gl->gl_object = ip;
293295
gfs2_glock_put(io_gl);
294296

295-
(*inode)->i_mode = DT2IF(DT_UNKNOWN);
297+
inode->i_mode = DT2IF(DT_UNKNOWN);
296298

297299
/*
298300
* 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,
303305
*/
304306
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
305307
&gh);
306-
if (unlikely(error)) {
307-
if (error == GLR_TRYFAILED)
308-
error = 0;
308+
if (unlikely(error))
309309
goto fail_glock;
310-
}
310+
311311
/* Inode is now uptodate */
312312
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;
314318

315-
return 0;
316319
fail_glock:
317320
gfs2_glock_dq(&ip->i_iopen_gh);
318321
fail_iopen:
@@ -321,7 +324,8 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
321324
ip->i_gl->gl_object = NULL;
322325
gfs2_glock_put(ip->i_gl);
323326
fail:
324-
return error;
327+
iget_failed(inode);
328+
return;
325329
}
326330

327331
static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)

fs/gfs2/inode.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip,
8484
extern void gfs2_set_iop(struct inode *inode);
8585
extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
8686
u64 no_addr, u64 no_formal_ino);
87-
extern int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
88-
struct inode **inode);
87+
extern void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr);
8988
extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
9089

9190
extern int gfs2_inode_refresh(struct gfs2_inode *ip);

fs/gfs2/log.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
696696
*
697697
*/
698698

699-
void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
699+
void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
700700
{
701701
struct gfs2_ail *ai;
702702

fs/gfs2/log.h

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,28 +47,21 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp,
4747
sdp->sd_log_head = sdp->sd_log_tail = value;
4848
}
4949

50-
unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
50+
extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
5151
unsigned int ssize);
5252

53-
int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
54-
void gfs2_log_incr_head(struct gfs2_sbd *sdp);
53+
extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
54+
extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
5555

56-
struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp);
57-
struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
56+
extern struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp);
57+
extern struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
5858
struct buffer_head *real);
59-
void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
59+
extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
60+
extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
61+
extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
6062

61-
static inline void gfs2_log_flush(struct gfs2_sbd *sbd, struct gfs2_glock *gl)
62-
{
63-
if (!gl || test_bit(GLF_LFLUSH, &gl->gl_flags))
64-
__gfs2_log_flush(sbd, gl);
65-
}
66-
67-
void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
68-
void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
69-
70-
void gfs2_log_shutdown(struct gfs2_sbd *sdp);
71-
void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
72-
int gfs2_logd(void *data);
63+
extern void gfs2_log_shutdown(struct gfs2_sbd *sdp);
64+
extern void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
65+
extern int gfs2_logd(void *data);
7366

7467
#endif /* __LOG_DOT_H__ */

fs/gfs2/rgrp.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,6 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
11921192
{
11931193
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
11941194
struct gfs2_alloc *al = ip->i_alloc;
1195-
struct inode *inode;
11961195
int error = 0;
11971196
u64 last_unlinked = NO_BLOCK, unlinked;
11981197

@@ -1210,22 +1209,27 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
12101209
if (error)
12111210
return error;
12121211

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. */
12131216
error = get_local_rgrp(ip, &unlinked, &last_unlinked);
12141217
if (error) {
12151218
if (ip != GFS2_I(sdp->sd_rindex))
12161219
gfs2_glock_dq_uninit(&al->al_ri_gh);
12171220
if (error != -EAGAIN)
12181221
return error;
1219-
error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb,
1220-
unlinked, &inode);
1221-
if (inode)
1222-
iput(inode);
1222+
1223+
gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked);
1224+
/* regardless of whether or not gfs2_process_unlinked_inode
1225+
was successful, we don't want to repeat it again. */
1226+
last_unlinked = unlinked;
12231227
gfs2_log_flush(sdp, NULL);
1224-
if (error == GLR_TRYFAILED)
1225-
error = 0;
1228+
error = 0;
1229+
12261230
goto try_again;
12271231
}
1228-
1232+
/* no error, so we have the rgrp set in the inode's allocation. */
12291233
al->al_file = file;
12301234
al->al_line = line;
12311235

0 commit comments

Comments
 (0)