Commit 160b4026 authored by Steven Whitehouse's avatar Steven Whitehouse

GFS2: Clean up symlink creation

This moves the symlink specific parts of inode creation
into the function where we initialise the rest of the
dinode. As a result we have one less place where we need
to look up the inode's buffer.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent e2d0a13b
...@@ -443,7 +443,8 @@ static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *par ...@@ -443,7 +443,8 @@ static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *par
static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
const struct gfs2_inum_host *inum, unsigned int mode, const struct gfs2_inum_host *inum, unsigned int mode,
unsigned int uid, unsigned int gid, unsigned int uid, unsigned int gid,
const u64 *generation, dev_t dev, struct buffer_head **bhp) const u64 *generation, dev_t dev, const char *symname,
unsigned size, struct buffer_head **bhp)
{ {
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
struct gfs2_dinode *di; struct gfs2_dinode *di;
...@@ -462,7 +463,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, ...@@ -462,7 +463,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
di->di_uid = cpu_to_be32(uid); di->di_uid = cpu_to_be32(uid);
di->di_gid = cpu_to_be32(gid); di->di_gid = cpu_to_be32(gid);
di->di_nlink = 0; di->di_nlink = 0;
di->di_size = 0; di->di_size = cpu_to_be64(size);
di->di_blocks = cpu_to_be64(1); di->di_blocks = cpu_to_be64(1);
di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
di->di_major = cpu_to_be32(MAJOR(dev)); di->di_major = cpu_to_be32(MAJOR(dev));
...@@ -484,17 +485,23 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, ...@@ -484,17 +485,23 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
memset(&di->di_reserved, 0, sizeof(di->di_reserved)); memset(&di->di_reserved, 0, sizeof(di->di_reserved));
if (S_ISREG(mode)) { switch(mode & S_IFMT) {
case S_IFREG:
if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) ||
gfs2_tune_get(sdp, gt_new_files_jdata)) gfs2_tune_get(sdp, gt_new_files_jdata))
di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
} else if (S_ISDIR(mode)) { break;
case S_IFDIR:
di->di_flags |= cpu_to_be32(dip->i_diskflags & di->di_flags |= cpu_to_be32(dip->i_diskflags &
GFS2_DIF_INHERIT_JDATA); GFS2_DIF_INHERIT_JDATA);
di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode));
di->di_entries = cpu_to_be32(2); di->di_entries = cpu_to_be32(2);
gfs2_init_dir(dibh, dip); gfs2_init_dir(dibh, dip);
break;
case S_IFLNK:
memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, size);
break;
} }
set_buffer_uptodate(dibh); set_buffer_uptodate(dibh);
...@@ -504,7 +511,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, ...@@ -504,7 +511,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
unsigned int mode, const struct gfs2_inum_host *inum, unsigned int mode, const struct gfs2_inum_host *inum,
const u64 *generation, dev_t dev, struct buffer_head **bhp) const u64 *generation, dev_t dev, const char *symname,
unsigned int size, struct buffer_head **bhp)
{ {
struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
unsigned int uid, gid; unsigned int uid, gid;
...@@ -526,7 +534,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, ...@@ -526,7 +534,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
if (error) if (error)
goto out_quota; goto out_quota;
init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, symname, size, bhp);
gfs2_quota_change(dip, +1, uid, gid); gfs2_quota_change(dip, +1, uid, gid);
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
...@@ -651,8 +659,10 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, ...@@ -651,8 +659,10 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
* Returns: An inode * Returns: An inode
*/ */
struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, static struct inode *gfs2_createi(struct gfs2_holder *ghs,
unsigned int mode, dev_t dev) const struct qstr *name, unsigned int mode,
dev_t dev, const char *symname,
unsigned int size)
{ {
struct inode *inode = NULL; struct inode *inode = NULL;
struct gfs2_inode *dip = ghs->gh_gl->gl_object; struct gfs2_inode *dip = ghs->gh_gl->gl_object;
...@@ -685,7 +695,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, ...@@ -685,7 +695,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
if (error) if (error)
goto fail_gunlock; goto fail_gunlock;
error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, symname, size, &bh);
if (error) if (error)
goto fail_gunlock2; goto fail_gunlock2;
...@@ -745,7 +755,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, ...@@ -745,7 +755,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
gfs2_holder_init(dip->i_gl, 0, 0, ghs); gfs2_holder_init(dip->i_gl, 0, 0, ghs);
for (;;) { for (;;) {
inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0, NULL, 0);
if (!IS_ERR(inode)) { if (!IS_ERR(inode)) {
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
if (dip->i_alloc->al_rgd) if (dip->i_alloc->al_rgd)
...@@ -1140,40 +1150,24 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) ...@@ -1140,40 +1150,24 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
static int gfs2_symlink(struct inode *dir, struct dentry *dentry, static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
const char *symname) const char *symname)
{ {
struct gfs2_inode *dip = GFS2_I(dir), *ip; struct gfs2_inode *dip = GFS2_I(dir);
struct gfs2_sbd *sdp = GFS2_SB(dir); struct gfs2_sbd *sdp = GFS2_SB(dir);
struct gfs2_holder ghs[2]; struct gfs2_holder ghs[2];
struct inode *inode; struct inode *inode;
struct buffer_head *dibh; unsigned int size;
int size;
int error;
/* Must be stuffed with a null terminator for gfs2_follow_link() */
size = strlen(symname); size = strlen(symname);
if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
return -ENAMETOOLONG; return -ENAMETOOLONG;
gfs2_holder_init(dip->i_gl, 0, 0, ghs); gfs2_holder_init(dip->i_gl, 0, 0, ghs);
inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0, symname, size);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
gfs2_holder_uninit(ghs); gfs2_holder_uninit(ghs);
return PTR_ERR(inode); return PTR_ERR(inode);
} }
ip = ghs[1].gh_gl->gl_object;
i_size_write(inode, size);
error = gfs2_meta_inode_buffer(ip, &dibh);
if (!gfs2_assert_withdraw(sdp, !error)) {
gfs2_dinode_out(ip, dibh->b_data);
memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname,
size);
brelse(dibh);
}
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
if (dip->i_alloc->al_rgd) if (dip->i_alloc->al_rgd)
gfs2_inplace_release(dip); gfs2_inplace_release(dip);
...@@ -1206,7 +1200,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -1206,7 +1200,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
gfs2_holder_init(dip->i_gl, 0, 0, ghs); gfs2_holder_init(dip->i_gl, 0, 0, ghs);
inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0, NULL, 0);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
gfs2_holder_uninit(ghs); gfs2_holder_uninit(ghs);
return PTR_ERR(inode); return PTR_ERR(inode);
...@@ -1245,7 +1239,7 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1245,7 +1239,7 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
gfs2_holder_init(dip->i_gl, 0, 0, ghs); gfs2_holder_init(dip->i_gl, 0, 0, ghs);
inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); inode = gfs2_createi(ghs, &dentry->d_name, mode, dev, NULL, 0);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
gfs2_holder_uninit(ghs); gfs2_holder_uninit(ghs);
return PTR_ERR(inode); return PTR_ERR(inode);
...@@ -1572,7 +1566,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -1572,7 +1566,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
struct gfs2_inode *ip = GFS2_I(dentry->d_inode); struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
struct gfs2_holder i_gh; struct gfs2_holder i_gh;
struct buffer_head *dibh; struct buffer_head *dibh;
unsigned int x, size; unsigned int size;
char *buf; char *buf;
int error; int error;
...@@ -1597,12 +1591,11 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -1597,12 +1591,11 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
goto out; goto out;
} }
x = size + 1; buf = kzalloc(size + 1, GFP_NOFS);
buf = kmalloc(x, GFP_NOFS);
if (!buf) if (!buf)
buf = ERR_PTR(-ENOMEM); buf = ERR_PTR(-ENOMEM);
else else
memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), x); memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), size);
brelse(dibh); brelse(dibh);
out: out:
gfs2_glock_dq_uninit(&i_gh); gfs2_glock_dq_uninit(&i_gh);
......
...@@ -108,9 +108,6 @@ extern int gfs2_inode_refresh(struct gfs2_inode *ip); ...@@ -108,9 +108,6 @@ extern int gfs2_inode_refresh(struct gfs2_inode *ip);
extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
int is_root); int is_root);
extern struct inode *gfs2_createi(struct gfs2_holder *ghs,
const struct qstr *name,
unsigned int mode, dev_t dev);
extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags);
extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);
......
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