From: Steven Whitehouse <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 09/24] GFS2: Add directory addition info structure
Date: Mon, 20 Jan 2014 12:23:32 +0000 [thread overview]
Message-ID: <1390220627-1571-10-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <1390220627-1571-1-git-send-email-swhiteho@redhat.com>
The intent is that this structure will hold the information
required when adding entries to a directory (linking). To
start with, it will contain only the number of blocks which
are required to link the new entry into the directory. The
current calculation returns either 0 or the maximim number of
blocks that can ever be requested by such a transaction.
The intent is that in a later patch, we can update the dir
code to calculate this value more accurately. In addition
further patches will also add further fields to the new
structure to increase its utility.
In addition this patch fixes a bug where the link used during
inode creation was adding requesting too many blocks in
some cases. This is harmless unless the fs is close to being
full.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 2e5fc26..0b6be20 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -2017,18 +2017,24 @@ out:
* gfs2_diradd_alloc_required - find if adding entry will require an allocation
* @ip: the file being written to
* @filname: the filename that's going to be added
+ * @da: The structure to return dir alloc info
*
- * Returns: 1 if alloc required, 0 if not, -ve on error
+ * Returns: 0 if ok, -ve on error
*/
-int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name)
+int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name,
+ struct gfs2_diradd *da)
{
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct gfs2_dirent *dent;
struct buffer_head *bh;
+ da->nr_blocks = 0;
+
dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh);
if (!dent) {
- return 1;
+ da->nr_blocks = sdp->sd_max_dirres;
+ return 0;
}
if (IS_ERR(dent))
return PTR_ERR(dent);
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
index 4f03bbd..c5573e7 100644
--- a/fs/gfs2/dir.h
+++ b/fs/gfs2/dir.h
@@ -17,6 +17,10 @@ struct inode;
struct gfs2_inode;
struct gfs2_inum;
+struct gfs2_diradd {
+ unsigned nr_blocks;
+};
+
extern struct inode *gfs2_dir_search(struct inode *dir,
const struct qstr *filename,
bool fail_on_exist);
@@ -33,7 +37,8 @@ extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
extern int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
extern int gfs2_diradd_alloc_required(struct inode *dir,
- const struct qstr *filename);
+ const struct qstr *filename,
+ struct gfs2_diradd *da);
extern int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
struct buffer_head **bhp);
extern void gfs2_dir_hash_inval(struct gfs2_inode *ip);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 7119504..9ac8f13 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -470,13 +470,13 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
}
static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
- struct gfs2_inode *ip, int arq)
+ struct gfs2_inode *ip, struct gfs2_diradd *da)
{
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
- struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
+ struct gfs2_alloc_parms ap = { .target = da->nr_blocks, };
int error;
- if (arq) {
+ if (da->nr_blocks) {
error = gfs2_quota_lock_check(dip);
if (error)
goto fail_quota_locks;
@@ -485,8 +485,8 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
if (error)
goto fail_quota_locks;
- error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
- dip->i_rgd->rd_length +
+ error = gfs2_trans_begin(sdp, da->nr_blocks +
+ gfs2_rg_blocks(dip, da->nr_blocks) +
2 * RES_DINODE +
RES_STATFS + RES_QUOTA, 0);
if (error)
@@ -560,7 +560,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
struct dentry *d;
int error;
u32 aflags = 0;
- int arq;
+ struct gfs2_diradd da;
if (!name->len || name->len > GFS2_FNAMESIZE)
return -ENAMETOOLONG;
@@ -602,7 +602,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
goto fail_gunlock;
}
- arq = error = gfs2_diradd_alloc_required(dir, name);
+ error = gfs2_diradd_alloc_required(dir, name, &da);
if (error < 0)
goto fail_gunlock;
@@ -690,7 +690,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
if (error)
goto fail_gunlock3;
- error = link_dinode(dip, name, ip, arq);
+ error = link_dinode(dip, name, ip, &da);
if (error)
goto fail_gunlock3;
@@ -817,7 +817,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder ghs[2];
struct buffer_head *dibh;
- int alloc_required;
+ struct gfs2_diradd da;
int error;
if (S_ISDIR(inode->i_mode))
@@ -872,13 +872,12 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
if (ip->i_inode.i_nlink == (u32)-1)
goto out_gunlock;
- alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
+ error = gfs2_diradd_alloc_required(dir, &dentry->d_name, &da);
if (error < 0)
goto out_gunlock;
- error = 0;
- if (alloc_required) {
- struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
+ if (da.nr_blocks) {
+ struct gfs2_alloc_parms ap = { .target = da.nr_blocks, };
error = gfs2_quota_lock_check(dip);
if (error)
goto out_gunlock;
@@ -887,8 +886,8 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
if (error)
goto out_gunlock_q;
- error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
- gfs2_rg_blocks(dip, sdp->sd_max_dirres) +
+ error = gfs2_trans_begin(sdp, da.nr_blocks +
+ gfs2_rg_blocks(dip, da.nr_blocks) +
2 * RES_DINODE + RES_STATFS +
RES_QUOTA, 0);
if (error)
@@ -919,10 +918,10 @@ out_brelse:
out_end_trans:
gfs2_trans_end(sdp);
out_ipres:
- if (alloc_required)
+ if (da.nr_blocks)
gfs2_inplace_release(dip);
out_gunlock_q:
- if (alloc_required)
+ if (da.nr_blocks)
gfs2_quota_unlock(dip);
out_gunlock:
gfs2_glock_dq(ghs + 1);
@@ -1254,7 +1253,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
struct gfs2_rgrpd *nrgd;
unsigned int num_gh;
int dir_rename = 0;
- int alloc_required = 0;
+ struct gfs2_diradd da = { .nr_blocks = 0, };
unsigned int x;
int error;
@@ -1388,14 +1387,14 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
goto out_gunlock;
}
- if (nip == NULL)
- alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
- error = alloc_required;
- if (error < 0)
- goto out_gunlock;
+ if (nip == NULL) {
+ error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name, &da);
+ if (error)
+ goto out_gunlock;
+ }
- if (alloc_required) {
- struct gfs2_alloc_parms ap = { .target = sdp->sd_max_dirres, };
+ if (da.nr_blocks) {
+ struct gfs2_alloc_parms ap = { .target = da.nr_blocks, };
error = gfs2_quota_lock_check(ndip);
if (error)
goto out_gunlock;
@@ -1404,8 +1403,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
if (error)
goto out_gunlock_q;
- error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
- gfs2_rg_blocks(ndip, sdp->sd_max_dirres) +
+ error = gfs2_trans_begin(sdp, da.nr_blocks +
+ gfs2_rg_blocks(ndip, da.nr_blocks) +
4 * RES_DINODE + 4 * RES_LEAF +
RES_STATFS + RES_QUOTA + 4, 0);
if (error)
@@ -1448,10 +1447,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
out_end_trans:
gfs2_trans_end(sdp);
out_ipreserv:
- if (alloc_required)
+ if (da.nr_blocks)
gfs2_inplace_release(ndip);
out_gunlock_q:
- if (alloc_required)
+ if (da.nr_blocks)
gfs2_quota_unlock(ndip);
out_gunlock:
while (x--) {
--
1.8.3.1
next prev parent reply other threads:[~2014-01-20 12:23 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-20 12:23 [Cluster-devel] GFS2: Pre-pull patch posting (merge window) Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 01/24] GFS2: If requested is too large, use the largest extent in the rgrp Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 02/24] GFS2: Drop inadequate rgrps from the reservation tree Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 03/24] GFS2: Implement a "rgrp has no extents longer than X" scheme Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 04/24] GFS2: Clean up releasepage Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 05/24] GFS2: Remove gfs2_quota_change_host structure Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 06/24] GFS2: Remove test which is always true Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 07/24] GFS2: Use range based functions for rgrp sync/invalidation Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 08/24] GFS2: Use only a single address space for rgrps Steven Whitehouse
2014-01-20 12:23 ` Steven Whitehouse [this message]
2014-01-20 12:23 ` [Cluster-devel] [PATCH 10/24] GFS2: Consolidate transaction blocks calculation for dir add Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 11/24] GFS2: Remember directory insert point Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 12/24] GFS2: Increase i_writecount during gfs2_setattr_chown Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 13/24] GFS2: For exhash conversion, only one block is needed Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 14/24] GFS2: Add hints to directory leaf blocks Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 15/24] GFS2: Add initialization for address space in super block Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 16/24] GFS2: No need to invalidate pages for a dio read Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 17/24] GFS2: Use RCU/hlist_bl based hash for quotas Steven Whitehouse
2014-01-22 5:32 ` Paul E. McKenney
2014-01-22 6:06 ` Sasha Levin
2014-01-22 9:43 ` Steven Whitehouse
2014-01-22 9:58 ` Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 18/24] GFS2: Only run logd and quota when mounted read/write Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 19/24] GFS2: Clean up quota slot allocation Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 20/24] GFS2: Move quota bitmap operations under their own lock Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 21/24] GFS2: Fix kbuild test robot reported warning Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 22/24] GFS2: Don't use ENOBUFS when ENOMEM is the correct error code Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 23/24] GFS2: Small cleanup Steven Whitehouse
2014-01-20 12:23 ` [Cluster-devel] [PATCH 24/24] GFS2: revert "GFS2: d_splice_alias() can't return error" Steven Whitehouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1390220627-1571-10-git-send-email-swhiteho@redhat.com \
--to=swhiteho@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).