Skip to content

Commit 677abe4

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw: GFS2: Fix typo GFS2: stuck in inode wait, no glocks stuck GFS2: Eliminate useless err variable GFS2: Fix writing to non-page aligned gfs2_quota structures GFS2: Add some useful messages GFS2: fix quota state reporting GFS2: Various gfs2_logd improvements GFS2: glock livelock GFS2: Clean up stuffed file copying GFS2: docs update GFS2: Remove space from slab cache name
2 parents e90e4d9 + 6a99be5 commit 677abe4

File tree

20 files changed

+368
-185
lines changed

20 files changed

+368
-185
lines changed

Documentation/filesystems/gfs2.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Global File System
22
------------------
33

4-
http://sources.redhat.com/cluster/
4+
http://sources.redhat.com/cluster/wiki/
55

66
GFS is a cluster file system. It allows a cluster of computers to
77
simultaneously use a block device that is shared between them (with FC,
@@ -36,11 +36,11 @@ GFS2 is not on-disk compatible with previous versions of GFS, but it
3636
is pretty close.
3737

3838
The following man pages can be found at the URL above:
39-
fsck.gfs2 to repair a filesystem
40-
gfs2_grow to expand a filesystem online
41-
gfs2_jadd to add journals to a filesystem online
42-
gfs2_tool to manipulate, examine and tune a filesystem
39+
fsck.gfs2 to repair a filesystem
40+
gfs2_grow to expand a filesystem online
41+
gfs2_jadd to add journals to a filesystem online
42+
gfs2_tool to manipulate, examine and tune a filesystem
4343
gfs2_quota to examine and change quota values in a filesystem
4444
gfs2_convert to convert a gfs filesystem to gfs2 in-place
4545
mount.gfs2 to help mount(8) mount a filesystem
46-
mkfs.gfs2 to make a filesystem
46+
mkfs.gfs2 to make a filesystem

fs/gfs2/aops.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ static int gfs2_jdata_writepages(struct address_space *mapping,
418418
static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
419419
{
420420
struct buffer_head *dibh;
421+
u64 dsize = i_size_read(&ip->i_inode);
421422
void *kaddr;
422423
int error;
423424

@@ -437,9 +438,10 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
437438
return error;
438439

439440
kaddr = kmap_atomic(page, KM_USER0);
440-
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
441-
ip->i_disksize);
442-
memset(kaddr + ip->i_disksize, 0, PAGE_CACHE_SIZE - ip->i_disksize);
441+
if (dsize > (dibh->b_size - sizeof(struct gfs2_dinode)))
442+
dsize = (dibh->b_size - sizeof(struct gfs2_dinode));
443+
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
444+
memset(kaddr + dsize, 0, PAGE_CACHE_SIZE - dsize);
443445
kunmap_atomic(kaddr, KM_USER0);
444446
flush_dcache_page(page);
445447
brelse(dibh);

fs/gfs2/bmap.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
7171

7272
if (!PageUptodate(page)) {
7373
void *kaddr = kmap(page);
74+
u64 dsize = i_size_read(inode);
75+
76+
if (dsize > (dibh->b_size - sizeof(struct gfs2_dinode)))
77+
dsize = dibh->b_size - sizeof(struct gfs2_dinode);
7478

75-
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
76-
ip->i_disksize);
77-
memset(kaddr + ip->i_disksize, 0,
78-
PAGE_CACHE_SIZE - ip->i_disksize);
79+
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
80+
memset(kaddr + dsize, 0, PAGE_CACHE_SIZE - dsize);
7981
kunmap(page);
8082

8183
SetPageUptodate(page);
@@ -1038,13 +1040,14 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
10381040
goto out;
10391041

10401042
if (gfs2_is_stuffed(ip)) {
1041-
ip->i_disksize = size;
1043+
u64 dsize = size + sizeof(struct gfs2_inode);
10421044
ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
10431045
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
10441046
gfs2_dinode_out(ip, dibh->b_data);
1045-
gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
1047+
if (dsize > dibh->b_size)
1048+
dsize = dibh->b_size;
1049+
gfs2_buffer_clear_tail(dibh, dsize);
10461050
error = 1;
1047-
10481051
} else {
10491052
if (size & (u64)(sdp->sd_sb.sb_bsize - 1))
10501053
error = gfs2_block_truncate_page(ip->i_inode.i_mapping);

fs/gfs2/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,7 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
14751475
inode = gfs2_inode_lookup(dir->i_sb,
14761476
be16_to_cpu(dent->de_type),
14771477
be64_to_cpu(dent->de_inum.no_addr),
1478-
be64_to_cpu(dent->de_inum.no_formal_ino), 0);
1478+
be64_to_cpu(dent->de_inum.no_formal_ino));
14791479
brelse(bh);
14801480
return inode;
14811481
}

fs/gfs2/export.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
168168
if (error)
169169
goto fail;
170170

171-
inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0, 0);
171+
inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0);
172172
if (IS_ERR(inode)) {
173173
error = PTR_ERR(inode);
174174
goto fail;

fs/gfs2/glock.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,9 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder *
855855
gh->gh_flags = flags;
856856
gh->gh_iflags = 0;
857857
gh->gh_ip = (unsigned long)__builtin_return_address(0);
858+
if (gh->gh_owner_pid)
859+
put_pid(gh->gh_owner_pid);
860+
gh->gh_owner_pid = get_pid(task_pid(current));
858861
}
859862

860863
/**

fs/gfs2/incore.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,6 @@ struct gfs2_args {
439439
struct gfs2_tune {
440440
spinlock_t gt_spin;
441441

442-
unsigned int gt_incore_log_blocks;
443-
unsigned int gt_log_flush_secs;
444-
445442
unsigned int gt_logd_secs;
446443

447444
unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
@@ -462,6 +459,7 @@ enum {
462459
SDF_SHUTDOWN = 2,
463460
SDF_NOBARRIERS = 3,
464461
SDF_NORECOVERY = 4,
462+
SDF_DEMOTE = 5,
465463
};
466464

467465
#define GFS2_FSNAME_LEN 256
@@ -618,6 +616,7 @@ struct gfs2_sbd {
618616
unsigned int sd_log_commited_databuf;
619617
int sd_log_commited_revoke;
620618

619+
atomic_t sd_log_pinned;
621620
unsigned int sd_log_num_buf;
622621
unsigned int sd_log_num_revoke;
623622
unsigned int sd_log_num_rg;
@@ -629,15 +628,17 @@ struct gfs2_sbd {
629628
struct list_head sd_log_le_databuf;
630629
struct list_head sd_log_le_ordered;
631630

631+
atomic_t sd_log_thresh1;
632+
atomic_t sd_log_thresh2;
632633
atomic_t sd_log_blks_free;
633-
struct mutex sd_log_reserve_mutex;
634+
wait_queue_head_t sd_log_waitq;
635+
wait_queue_head_t sd_logd_waitq;
634636

635637
u64 sd_log_sequence;
636638
unsigned int sd_log_head;
637639
unsigned int sd_log_tail;
638640
int sd_log_idle;
639641

640-
unsigned long sd_log_flush_time;
641642
struct rw_semaphore sd_log_flush_lock;
642643
atomic_t sd_log_in_flight;
643644
wait_queue_head_t sd_log_flush_wait;

fs/gfs2/inode.c

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,25 +158,21 @@ void gfs2_set_iop(struct inode *inode)
158158
* @sb: The super block
159159
* @no_addr: The inode number
160160
* @type: The type of the inode
161-
* @skip_freeing: set this not return an inode if it is currently being freed.
162161
*
163162
* Returns: A VFS inode, or an error
164163
*/
165164

166165
struct inode *gfs2_inode_lookup(struct super_block *sb,
167166
unsigned int type,
168167
u64 no_addr,
169-
u64 no_formal_ino, int skip_freeing)
168+
u64 no_formal_ino)
170169
{
171170
struct inode *inode;
172171
struct gfs2_inode *ip;
173172
struct gfs2_glock *io_gl;
174173
int error;
175174

176-
if (skip_freeing)
177-
inode = gfs2_iget_skip(sb, no_addr);
178-
else
179-
inode = gfs2_iget(sb, no_addr);
175+
inode = gfs2_iget(sb, no_addr);
180176
ip = GFS2_I(inode);
181177

182178
if (!inode)
@@ -234,13 +230,100 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
234230
fail_iopen:
235231
gfs2_glock_put(io_gl);
236232
fail_put:
237-
ip->i_gl->gl_object = NULL;
233+
if (inode->i_state & I_NEW)
234+
ip->i_gl->gl_object = NULL;
238235
gfs2_glock_put(ip->i_gl);
239236
fail:
240-
iget_failed(inode);
237+
if (inode->i_state & I_NEW)
238+
iget_failed(inode);
239+
else
240+
iput(inode);
241241
return ERR_PTR(error);
242242
}
243243

244+
/**
245+
* gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation
246+
* @sb: The super block
247+
* no_addr: The inode number
248+
* @@inode: A pointer to the inode found, if any
249+
*
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+
254+
int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
255+
struct inode **inode)
256+
{
257+
struct gfs2_sbd *sdp;
258+
struct gfs2_inode *ip;
259+
struct gfs2_glock *io_gl;
260+
int error;
261+
struct gfs2_holder gh;
262+
263+
*inode = gfs2_iget_skip(sb, no_addr);
264+
265+
if (!(*inode))
266+
return -ENOBUFS;
267+
268+
if (!((*inode)->i_state & I_NEW))
269+
return -ENOBUFS;
270+
271+
ip = GFS2_I(*inode);
272+
sdp = GFS2_SB(*inode);
273+
ip->i_no_formal_ino = -1;
274+
275+
error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
276+
if (unlikely(error))
277+
goto fail;
278+
ip->i_gl->gl_object = ip;
279+
280+
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
281+
if (unlikely(error))
282+
goto fail_put;
283+
284+
set_bit(GIF_INVALID, &ip->i_flags);
285+
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT,
286+
&ip->i_iopen_gh);
287+
if (unlikely(error)) {
288+
if (error == GLR_TRYFAILED)
289+
error = 0;
290+
goto fail_iopen;
291+
}
292+
ip->i_iopen_gh.gh_gl->gl_object = ip;
293+
gfs2_glock_put(io_gl);
294+
295+
(*inode)->i_mode = DT2IF(DT_UNKNOWN);
296+
297+
/*
298+
* We must read the inode in order to work out its type in
299+
* this case. Note that this doesn't happen often as we normally
300+
* know the type beforehand. This code path only occurs during
301+
* unlinked inode recovery (where it is safe to do this glock,
302+
* which is not true in the general case).
303+
*/
304+
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
305+
&gh);
306+
if (unlikely(error)) {
307+
if (error == GLR_TRYFAILED)
308+
error = 0;
309+
goto fail_glock;
310+
}
311+
/* Inode is now uptodate */
312+
gfs2_glock_dq_uninit(&gh);
313+
gfs2_set_iop(*inode);
314+
315+
return 0;
316+
fail_glock:
317+
gfs2_glock_dq(&ip->i_iopen_gh);
318+
fail_iopen:
319+
gfs2_glock_put(io_gl);
320+
fail_put:
321+
ip->i_gl->gl_object = NULL;
322+
gfs2_glock_put(ip->i_gl);
323+
fail:
324+
return error;
325+
}
326+
244327
static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
245328
{
246329
const struct gfs2_dinode *str = buf;
@@ -862,7 +945,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
862945
goto fail_gunlock2;
863946

864947
inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr,
865-
inum.no_formal_ino, 0);
948+
inum.no_formal_ino);
866949
if (IS_ERR(inode))
867950
goto fail_gunlock2;
868951

fs/gfs2/inode.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip,
8383

8484
extern void gfs2_set_iop(struct inode *inode);
8585
extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
86-
u64 no_addr, u64 no_formal_ino,
87-
int skip_freeing);
86+
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);
8889
extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
8990

9091
extern int gfs2_inode_refresh(struct gfs2_inode *ip);

0 commit comments

Comments
 (0)