Commit 37504a3b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gfs2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes

Pull gfs2 fixes from Steven Whitehouse:
 "Here are a number of small fixes for GFS2.

  There is a fix for FIEMAP on large sparse files, a negative dentry
  hashing fix, a fix for flock, and a bug fix relating to d_splice_alias
  usage.

  There are also (patches 1 and 5) a couple of updates which are less
  critical, but small and low risk"

* tag 'gfs2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes:
  GFS2: fix d_splice_alias() misuses
  GFS2: Don't use MAXQUOTAS value
  GFS2: Hash the negative dentry during inode lookup
  GFS2: Request demote when a "try" flock fails
  GFS2: Change maxlen variables to size_t
  GFS2: fs/gfs2/super.c: replace seq_printf by seq_puts
parents a060dc50 cfb2f9d5
...@@ -359,7 +359,7 @@ static inline void release_metapath(struct metapath *mp) ...@@ -359,7 +359,7 @@ static inline void release_metapath(struct metapath *mp)
* Returns: The length of the extent (minimum of one block) * Returns: The length of the extent (minimum of one block)
*/ */
static inline unsigned int gfs2_extent_length(void *start, unsigned int len, __be64 *ptr, unsigned limit, int *eob) static inline unsigned int gfs2_extent_length(void *start, unsigned int len, __be64 *ptr, size_t limit, int *eob)
{ {
const __be64 *end = (start + len); const __be64 *end = (start + len);
const __be64 *first = ptr; const __be64 *first = ptr;
...@@ -449,7 +449,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, ...@@ -449,7 +449,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
struct buffer_head *bh_map, struct metapath *mp, struct buffer_head *bh_map, struct metapath *mp,
const unsigned int sheight, const unsigned int sheight,
const unsigned int height, const unsigned int height,
const unsigned int maxlen) const size_t maxlen)
{ {
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
...@@ -483,7 +483,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, ...@@ -483,7 +483,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
} else { } else {
/* Need to allocate indirect blocks */ /* Need to allocate indirect blocks */
ptrs_per_blk = height > 1 ? sdp->sd_inptrs : sdp->sd_diptrs; ptrs_per_blk = height > 1 ? sdp->sd_inptrs : sdp->sd_diptrs;
dblks = min(maxlen, ptrs_per_blk - mp->mp_list[end_of_metadata]); dblks = min(maxlen, (size_t)(ptrs_per_blk -
mp->mp_list[end_of_metadata]));
if (height == ip->i_height) { if (height == ip->i_height) {
/* Writing into existing tree, extend tree down */ /* Writing into existing tree, extend tree down */
iblks = height - sheight; iblks = height - sheight;
...@@ -605,7 +606,7 @@ int gfs2_block_map(struct inode *inode, sector_t lblock, ...@@ -605,7 +606,7 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_sbd *sdp = GFS2_SB(inode);
unsigned int bsize = sdp->sd_sb.sb_bsize; unsigned int bsize = sdp->sd_sb.sb_bsize;
const unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; const size_t maxlen = bh_map->b_size >> inode->i_blkbits;
const u64 *arr = sdp->sd_heightsize; const u64 *arr = sdp->sd_heightsize;
__be64 *ptr; __be64 *ptr;
u64 size; u64 size;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/dlm.h> #include <linux/dlm.h>
#include <linux/dlm_plock.h> #include <linux/dlm_plock.h>
#include <linux/aio.h> #include <linux/aio.h>
#include <linux/delay.h>
#include "gfs2.h" #include "gfs2.h"
#include "incore.h" #include "incore.h"
...@@ -979,9 +980,10 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) ...@@ -979,9 +980,10 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
unsigned int state; unsigned int state;
int flags; int flags;
int error = 0; int error = 0;
int sleeptime;
state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED;
flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT; flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY_1CB) | GL_EXACT;
mutex_lock(&fp->f_fl_mutex); mutex_lock(&fp->f_fl_mutex);
...@@ -1001,7 +1003,14 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) ...@@ -1001,7 +1003,14 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
gfs2_holder_init(gl, state, flags, fl_gh); gfs2_holder_init(gl, state, flags, fl_gh);
gfs2_glock_put(gl); gfs2_glock_put(gl);
} }
error = gfs2_glock_nq(fl_gh); for (sleeptime = 1; sleeptime <= 4; sleeptime <<= 1) {
error = gfs2_glock_nq(fl_gh);
if (error != GLR_TRYFAILED)
break;
fl_gh->gh_flags = LM_FLAG_TRY | GL_EXACT;
fl_gh->gh_error = 0;
msleep(sleeptime);
}
if (error) { if (error) {
gfs2_holder_uninit(fl_gh); gfs2_holder_uninit(fl_gh);
if (error == GLR_TRYFAILED) if (error == GLR_TRYFAILED)
...@@ -1024,7 +1033,7 @@ static void do_unflock(struct file *file, struct file_lock *fl) ...@@ -1024,7 +1033,7 @@ static void do_unflock(struct file *file, struct file_lock *fl)
mutex_lock(&fp->f_fl_mutex); mutex_lock(&fp->f_fl_mutex);
flock_lock_file_wait(file, fl); flock_lock_file_wait(file, fl);
if (fl_gh->gh_gl) { if (fl_gh->gh_gl) {
gfs2_glock_dq_wait(fl_gh); gfs2_glock_dq(fl_gh);
gfs2_holder_uninit(fl_gh); gfs2_holder_uninit(fl_gh);
} }
mutex_unlock(&fp->f_fl_mutex); mutex_unlock(&fp->f_fl_mutex);
......
...@@ -262,6 +262,9 @@ struct gfs2_holder { ...@@ -262,6 +262,9 @@ struct gfs2_holder {
unsigned long gh_ip; unsigned long gh_ip;
}; };
/* Number of quota types we support */
#define GFS2_MAXQUOTAS 2
/* Resource group multi-block reservation, in order of appearance: /* Resource group multi-block reservation, in order of appearance:
Step 1. Function prepares to write, allocates a mb, sets the size hint. Step 1. Function prepares to write, allocates a mb, sets the size hint.
...@@ -282,8 +285,8 @@ struct gfs2_blkreserv { ...@@ -282,8 +285,8 @@ struct gfs2_blkreserv {
u64 rs_inum; /* Inode number for reservation */ u64 rs_inum; /* Inode number for reservation */
/* ancillary quota stuff */ /* ancillary quota stuff */
struct gfs2_quota_data *rs_qa_qd[2 * MAXQUOTAS]; struct gfs2_quota_data *rs_qa_qd[2 * GFS2_MAXQUOTAS];
struct gfs2_holder rs_qa_qd_ghs[2 * MAXQUOTAS]; struct gfs2_holder rs_qa_qd_ghs[2 * GFS2_MAXQUOTAS];
unsigned int rs_qa_qd_num; unsigned int rs_qa_qd_num;
}; };
......
...@@ -626,8 +626,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -626,8 +626,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
d = d_splice_alias(inode, dentry); d = d_splice_alias(inode, dentry);
error = PTR_ERR(d); error = PTR_ERR(d);
if (IS_ERR(d)) if (IS_ERR(d)) {
inode = ERR_CAST(d);
goto fail_gunlock; goto fail_gunlock;
}
error = 0; error = 0;
if (file) { if (file) {
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
...@@ -840,8 +842,10 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry, ...@@ -840,8 +842,10 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry,
int error; int error;
inode = gfs2_lookupi(dir, &dentry->d_name, 0); inode = gfs2_lookupi(dir, &dentry->d_name, 0);
if (!inode) if (inode == NULL) {
d_add(dentry, NULL);
return NULL; return NULL;
}
if (IS_ERR(inode)) if (IS_ERR(inode))
return ERR_CAST(inode); return ERR_CAST(inode);
...@@ -854,7 +858,6 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry, ...@@ -854,7 +858,6 @@ static struct dentry *__gfs2_lookup(struct inode *dir, struct dentry *dentry,
d = d_splice_alias(inode, dentry); d = d_splice_alias(inode, dentry);
if (IS_ERR(d)) { if (IS_ERR(d)) {
iput(inode);
gfs2_glock_dq_uninit(&gh); gfs2_glock_dq_uninit(&gh);
return d; return d;
} }
......
...@@ -1294,7 +1294,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) ...@@ -1294,7 +1294,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
int val; int val;
if (is_ancestor(root, sdp->sd_master_dir)) if (is_ancestor(root, sdp->sd_master_dir))
seq_printf(s, ",meta"); seq_puts(s, ",meta");
if (args->ar_lockproto[0]) if (args->ar_lockproto[0])
seq_printf(s, ",lockproto=%s", args->ar_lockproto); seq_printf(s, ",lockproto=%s", args->ar_lockproto);
if (args->ar_locktable[0]) if (args->ar_locktable[0])
...@@ -1302,13 +1302,13 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) ...@@ -1302,13 +1302,13 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
if (args->ar_hostdata[0]) if (args->ar_hostdata[0])
seq_printf(s, ",hostdata=%s", args->ar_hostdata); seq_printf(s, ",hostdata=%s", args->ar_hostdata);
if (args->ar_spectator) if (args->ar_spectator)
seq_printf(s, ",spectator"); seq_puts(s, ",spectator");
if (args->ar_localflocks) if (args->ar_localflocks)
seq_printf(s, ",localflocks"); seq_puts(s, ",localflocks");
if (args->ar_debug) if (args->ar_debug)
seq_printf(s, ",debug"); seq_puts(s, ",debug");
if (args->ar_posix_acl) if (args->ar_posix_acl)
seq_printf(s, ",acl"); seq_puts(s, ",acl");
if (args->ar_quota != GFS2_QUOTA_DEFAULT) { if (args->ar_quota != GFS2_QUOTA_DEFAULT) {
char *state; char *state;
switch (args->ar_quota) { switch (args->ar_quota) {
...@@ -1328,7 +1328,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) ...@@ -1328,7 +1328,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
seq_printf(s, ",quota=%s", state); seq_printf(s, ",quota=%s", state);
} }
if (args->ar_suiddir) if (args->ar_suiddir)
seq_printf(s, ",suiddir"); seq_puts(s, ",suiddir");
if (args->ar_data != GFS2_DATA_DEFAULT) { if (args->ar_data != GFS2_DATA_DEFAULT) {
char *state; char *state;
switch (args->ar_data) { switch (args->ar_data) {
...@@ -1345,7 +1345,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) ...@@ -1345,7 +1345,7 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
seq_printf(s, ",data=%s", state); seq_printf(s, ",data=%s", state);
} }
if (args->ar_discard) if (args->ar_discard)
seq_printf(s, ",discard"); seq_puts(s, ",discard");
val = sdp->sd_tune.gt_logd_secs; val = sdp->sd_tune.gt_logd_secs;
if (val != 30) if (val != 30)
seq_printf(s, ",commit=%d", val); seq_printf(s, ",commit=%d", val);
...@@ -1376,11 +1376,11 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) ...@@ -1376,11 +1376,11 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
seq_printf(s, ",errors=%s", state); seq_printf(s, ",errors=%s", state);
} }
if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
seq_printf(s, ",nobarrier"); seq_puts(s, ",nobarrier");
if (test_bit(SDF_DEMOTE, &sdp->sd_flags)) if (test_bit(SDF_DEMOTE, &sdp->sd_flags))
seq_printf(s, ",demote_interface_used"); seq_puts(s, ",demote_interface_used");
if (args->ar_rgrplvb) if (args->ar_rgrplvb)
seq_printf(s, ",rgrplvb"); seq_puts(s, ",rgrplvb");
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment