Skip to content

Commit 445e1ce

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: Support for I/O barriers GFS2: Add UUID to GFS2 sb GFS2: high time to take some time over atime GFS2: The war on bloat GFS2: GFS2 will panic if you misspell any mount options GFS2: Direct IO write at end of file error GFS2: Use an IS_ERR test rather than a NULL test GFS2: Fix race relating to glock min-hold time GFS2: Fix & clean up GFS2 rename GFS2: rm on multiple nodes causes panic GFS2: Fix metafs mounts GFS2: Fix debugfs glock file iterator
2 parents ef5bef3 + 254db57 commit 445e1ce

File tree

16 files changed

+654
-799
lines changed

16 files changed

+654
-799
lines changed

fs/gfs2/glock.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,8 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name,
12651265
holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time;
12661266
if (time_before(now, holdtime))
12671267
delay = holdtime - now;
1268+
if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags))
1269+
delay = gl->gl_ops->go_min_hold_time;
12681270

12691271
spin_lock(&gl->gl_spin);
12701272
handle_callback(gl, state, 1, delay);
@@ -1578,8 +1580,6 @@ static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags)
15781580
*p++ = 'a';
15791581
if (flags & GL_EXACT)
15801582
*p++ = 'E';
1581-
if (flags & GL_ATIME)
1582-
*p++ = 'a';
15831583
if (flags & GL_NOCACHE)
15841584
*p++ = 'c';
15851585
if (test_bit(HIF_HOLDER, &iflags))
@@ -1816,15 +1816,17 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
18161816
if (gl) {
18171817
gi->gl = hlist_entry(gl->gl_list.next,
18181818
struct gfs2_glock, gl_list);
1819-
if (gi->gl)
1820-
gfs2_glock_hold(gi->gl);
1819+
} else {
1820+
gi->gl = hlist_entry(gl_hash_table[gi->hash].hb_list.first,
1821+
struct gfs2_glock, gl_list);
18211822
}
1823+
if (gi->gl)
1824+
gfs2_glock_hold(gi->gl);
18221825
read_unlock(gl_lock_addr(gi->hash));
18231826
if (gl)
18241827
gfs2_glock_put(gl);
1825-
if (gl && gi->gl == NULL)
1826-
gi->hash++;
18271828
while (gi->gl == NULL) {
1829+
gi->hash++;
18281830
if (gi->hash >= GFS2_GL_HASH_SIZE)
18291831
return 1;
18301832
read_lock(gl_lock_addr(gi->hash));
@@ -1833,7 +1835,6 @@ static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
18331835
if (gi->gl)
18341836
gfs2_glock_hold(gi->gl);
18351837
read_unlock(gl_lock_addr(gi->hash));
1836-
gi->hash++;
18371838
}
18381839

18391840
if (gi->sdp != gi->gl->gl_sbd)

fs/gfs2/glock.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#define GL_ASYNC 0x00000040
2525
#define GL_EXACT 0x00000080
2626
#define GL_SKIP 0x00000100
27-
#define GL_ATIME 0x00000200
2827
#define GL_NOCACHE 0x00000400
2928

3029
#define GLR_TRYFAILED 13

fs/gfs2/incore.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -386,20 +386,21 @@ struct gfs2_statfs_change_host {
386386
#define GFS2_DATA_ORDERED 2
387387

388388
struct gfs2_args {
389-
char ar_lockproto[GFS2_LOCKNAME_LEN]; /* Name of the Lock Protocol */
390-
char ar_locktable[GFS2_LOCKNAME_LEN]; /* Name of the Lock Table */
391-
char ar_hostdata[GFS2_LOCKNAME_LEN]; /* Host specific data */
392-
int ar_spectator; /* Don't get a journal because we're always RO */
393-
int ar_ignore_local_fs; /* Don't optimize even if local_fs is 1 */
394-
int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */
395-
int ar_localcaching; /* Local-style caching (dangerous on multihost) */
396-
int ar_debug; /* Oops on errors instead of trying to be graceful */
397-
int ar_upgrade; /* Upgrade ondisk/multihost format */
398-
unsigned int ar_num_glockd; /* Number of glockd threads */
399-
int ar_posix_acl; /* Enable posix acls */
400-
int ar_quota; /* off/account/on */
401-
int ar_suiddir; /* suiddir support */
402-
int ar_data; /* ordered/writeback */
389+
char ar_lockproto[GFS2_LOCKNAME_LEN]; /* Name of the Lock Protocol */
390+
char ar_locktable[GFS2_LOCKNAME_LEN]; /* Name of the Lock Table */
391+
char ar_hostdata[GFS2_LOCKNAME_LEN]; /* Host specific data */
392+
unsigned int ar_spectator:1; /* Don't get a journal */
393+
unsigned int ar_ignore_local_fs:1; /* Ignore optimisations */
394+
unsigned int ar_localflocks:1; /* Let the VFS do flock|fcntl */
395+
unsigned int ar_localcaching:1; /* Local caching */
396+
unsigned int ar_debug:1; /* Oops on errors */
397+
unsigned int ar_upgrade:1; /* Upgrade ondisk format */
398+
unsigned int ar_posix_acl:1; /* Enable posix acls */
399+
unsigned int ar_quota:2; /* off/account/on */
400+
unsigned int ar_suiddir:1; /* suiddir support */
401+
unsigned int ar_data:2; /* ordered/writeback */
402+
unsigned int ar_meta:1; /* mount metafs */
403+
unsigned int ar_num_glockd; /* Number of glockd threads */
403404
};
404405

405406
struct gfs2_tune {
@@ -419,7 +420,6 @@ struct gfs2_tune {
419420
unsigned int gt_quota_scale_den; /* Denominator */
420421
unsigned int gt_quota_cache_secs;
421422
unsigned int gt_quota_quantum; /* Secs between syncs to quota file */
422-
unsigned int gt_atime_quantum; /* Min secs between atime updates */
423423
unsigned int gt_new_files_jdata;
424424
unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */
425425
unsigned int gt_stall_secs; /* Detects trouble! */
@@ -432,7 +432,7 @@ enum {
432432
SDF_JOURNAL_CHECKED = 0,
433433
SDF_JOURNAL_LIVE = 1,
434434
SDF_SHUTDOWN = 2,
435-
SDF_NOATIME = 3,
435+
SDF_NOBARRIERS = 3,
436436
};
437437

438438
#define GFS2_FSNAME_LEN 256
@@ -461,7 +461,6 @@ struct gfs2_sb_host {
461461

462462
struct gfs2_sbd {
463463
struct super_block *sd_vfs;
464-
struct super_block *sd_vfs_meta;
465464
struct kobject sd_kobj;
466465
unsigned long sd_flags; /* SDF_... */
467466
struct gfs2_sb_host sd_sb;
@@ -499,7 +498,9 @@ struct gfs2_sbd {
499498

500499
/* Inode Stuff */
501500

502-
struct inode *sd_master_dir;
501+
struct dentry *sd_master_dir;
502+
struct dentry *sd_root_dir;
503+
503504
struct inode *sd_jindex;
504505
struct inode *sd_inum_inode;
505506
struct inode *sd_statfs_inode;
@@ -634,7 +635,6 @@ struct gfs2_sbd {
634635
/* Debugging crud */
635636

636637
unsigned long sd_last_warning;
637-
struct vfsmount *sd_gfs2mnt;
638638
struct dentry *debugfs_dir; /* debugfs directory */
639639
struct dentry *debugfs_dentry_glocks; /* for debugfs */
640640
};

fs/gfs2/inode.c

Lines changed: 9 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/crc32.h>
1919
#include <linux/lm_interface.h>
2020
#include <linux/security.h>
21+
#include <linux/time.h>
2122

2223
#include "gfs2.h"
2324
#include "incore.h"
@@ -249,6 +250,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
249250
{
250251
struct gfs2_dinode_host *di = &ip->i_di;
251252
const struct gfs2_dinode *str = buf;
253+
struct timespec atime;
252254
u16 height, depth;
253255

254256
if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
@@ -275,8 +277,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
275277
di->di_size = be64_to_cpu(str->di_size);
276278
i_size_write(&ip->i_inode, di->di_size);
277279
gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
278-
ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
279-
ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
280+
atime.tv_sec = be64_to_cpu(str->di_atime);
281+
atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
282+
if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0)
283+
ip->i_inode.i_atime = atime;
280284
ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
281285
ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
282286
ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
@@ -1033,13 +1037,11 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
10331037

10341038
if (bh)
10351039
brelse(bh);
1036-
if (!inode)
1037-
return ERR_PTR(-ENOMEM);
10381040
return inode;
10391041

10401042
fail_gunlock2:
10411043
gfs2_glock_dq_uninit(ghs + 1);
1042-
if (inode)
1044+
if (inode && !IS_ERR(inode))
10431045
iput(inode);
10441046
fail_gunlock:
10451047
gfs2_glock_dq(ghs);
@@ -1140,54 +1142,6 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
11401142
return 0;
11411143
}
11421144

1143-
/*
1144-
* gfs2_ok_to_move - check if it's ok to move a directory to another directory
1145-
* @this: move this
1146-
* @to: to here
1147-
*
1148-
* Follow @to back to the root and make sure we don't encounter @this
1149-
* Assumes we already hold the rename lock.
1150-
*
1151-
* Returns: errno
1152-
*/
1153-
1154-
int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1155-
{
1156-
struct inode *dir = &to->i_inode;
1157-
struct super_block *sb = dir->i_sb;
1158-
struct inode *tmp;
1159-
struct qstr dotdot;
1160-
int error = 0;
1161-
1162-
gfs2_str2qstr(&dotdot, "..");
1163-
1164-
igrab(dir);
1165-
1166-
for (;;) {
1167-
if (dir == &this->i_inode) {
1168-
error = -EINVAL;
1169-
break;
1170-
}
1171-
if (dir == sb->s_root->d_inode) {
1172-
error = 0;
1173-
break;
1174-
}
1175-
1176-
tmp = gfs2_lookupi(dir, &dotdot, 1);
1177-
if (IS_ERR(tmp)) {
1178-
error = PTR_ERR(tmp);
1179-
break;
1180-
}
1181-
1182-
iput(dir);
1183-
dir = tmp;
1184-
}
1185-
1186-
iput(dir);
1187-
1188-
return error;
1189-
}
1190-
11911145
/**
11921146
* gfs2_readlinki - return the contents of a symlink
11931147
* @ip: the symlink's inode
@@ -1207,8 +1161,8 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
12071161
unsigned int x;
12081162
int error;
12091163

1210-
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
1211-
error = gfs2_glock_nq_atime(&i_gh);
1164+
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
1165+
error = gfs2_glock_nq(&i_gh);
12121166
if (error) {
12131167
gfs2_holder_uninit(&i_gh);
12141168
return error;
@@ -1243,101 +1197,6 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
12431197
return error;
12441198
}
12451199

1246-
/**
1247-
* gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and
1248-
* conditionally update the inode's atime
1249-
* @gh: the holder to acquire
1250-
*
1251-
* Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap
1252-
* Update if the difference between the current time and the inode's current
1253-
* atime is greater than an interval specified at mount.
1254-
*
1255-
* Returns: errno
1256-
*/
1257-
1258-
int gfs2_glock_nq_atime(struct gfs2_holder *gh)
1259-
{
1260-
struct gfs2_glock *gl = gh->gh_gl;
1261-
struct gfs2_sbd *sdp = gl->gl_sbd;
1262-
struct gfs2_inode *ip = gl->gl_object;
1263-
s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
1264-
unsigned int state;
1265-
int flags;
1266-
int error;
1267-
struct timespec tv = CURRENT_TIME;
1268-
1269-
if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
1270-
gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
1271-
gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops))
1272-
return -EINVAL;
1273-
1274-
state = gh->gh_state;
1275-
flags = gh->gh_flags;
1276-
1277-
error = gfs2_glock_nq(gh);
1278-
if (error)
1279-
return error;
1280-
1281-
if (test_bit(SDF_NOATIME, &sdp->sd_flags) ||
1282-
(sdp->sd_vfs->s_flags & MS_RDONLY))
1283-
return 0;
1284-
1285-
if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
1286-
gfs2_glock_dq(gh);
1287-
gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
1288-
gh);
1289-
error = gfs2_glock_nq(gh);
1290-
if (error)
1291-
return error;
1292-
1293-
/* Verify that atime hasn't been updated while we were
1294-
trying to get exclusive lock. */
1295-
1296-
tv = CURRENT_TIME;
1297-
if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
1298-
struct buffer_head *dibh;
1299-
struct gfs2_dinode *di;
1300-
1301-
error = gfs2_trans_begin(sdp, RES_DINODE, 0);
1302-
if (error == -EROFS)
1303-
return 0;
1304-
if (error)
1305-
goto fail;
1306-
1307-
error = gfs2_meta_inode_buffer(ip, &dibh);
1308-
if (error)
1309-
goto fail_end_trans;
1310-
1311-
ip->i_inode.i_atime = tv;
1312-
1313-
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1314-
di = (struct gfs2_dinode *)dibh->b_data;
1315-
di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
1316-
di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
1317-
brelse(dibh);
1318-
1319-
gfs2_trans_end(sdp);
1320-
}
1321-
1322-
/* If someone else has asked for the glock,
1323-
unlock and let them have it. Then reacquire
1324-
in the original state. */
1325-
if (gfs2_glock_is_blocking(gl)) {
1326-
gfs2_glock_dq(gh);
1327-
gfs2_holder_reinit(state, flags, gh);
1328-
return gfs2_glock_nq(gh);
1329-
}
1330-
}
1331-
1332-
return 0;
1333-
1334-
fail_end_trans:
1335-
gfs2_trans_end(sdp);
1336-
fail:
1337-
gfs2_glock_dq(gh);
1338-
return error;
1339-
}
1340-
13411200
static int
13421201
__gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
13431202
{

fs/gfs2/inode.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
9191
int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
9292
const struct gfs2_inode *ip);
9393
int gfs2_permission(struct inode *inode, int mask);
94-
int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to);
9594
int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len);
96-
int gfs2_glock_nq_atime(struct gfs2_holder *gh);
9795
int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
9896
struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
9997
void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf);

fs/gfs2/log.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/delay.h>
1919
#include <linux/kthread.h>
2020
#include <linux/freezer.h>
21+
#include <linux/bio.h>
2122

2223
#include "gfs2.h"
2324
#include "incore.h"
@@ -584,7 +585,6 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
584585
memset(bh->b_data, 0, bh->b_size);
585586
set_buffer_uptodate(bh);
586587
clear_buffer_dirty(bh);
587-
unlock_buffer(bh);
588588

589589
gfs2_ail1_empty(sdp, 0);
590590
tail = current_tail(sdp);
@@ -601,8 +601,23 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
601601
hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header));
602602
lh->lh_hash = cpu_to_be32(hash);
603603

604-
set_buffer_dirty(bh);
605-
if (sync_dirty_buffer(bh))
604+
bh->b_end_io = end_buffer_write_sync;
605+
if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
606+
goto skip_barrier;
607+
get_bh(bh);
608+
submit_bh(WRITE_BARRIER | (1 << BIO_RW_META), bh);
609+
wait_on_buffer(bh);
610+
if (buffer_eopnotsupp(bh)) {
611+
clear_buffer_eopnotsupp(bh);
612+
set_buffer_uptodate(bh);
613+
set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
614+
lock_buffer(bh);
615+
skip_barrier:
616+
get_bh(bh);
617+
submit_bh(WRITE_SYNC | (1 << BIO_RW_META), bh);
618+
wait_on_buffer(bh);
619+
}
620+
if (!buffer_uptodate(bh))
606621
gfs2_io_error_bh(sdp, bh);
607622
brelse(bh);
608623

0 commit comments

Comments
 (0)