Commit 8d123585 authored by Steven Whitehouse's avatar Steven Whitehouse

GFS2: Make . and .. qstrs constant

Rather than calculating the qstrs for . and .. each time
we need them, its better to keep a constant version of
these and just refer to them when required.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@infradead.org>
parent 9fa0ea9f
...@@ -79,6 +79,9 @@ ...@@ -79,6 +79,9 @@
#define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1) #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1)
#define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1)) #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1))
struct qstr gfs2_qdot __read_mostly;
struct qstr gfs2_qdotdot __read_mostly;
typedef int (*leaf_call_t) (struct gfs2_inode *dip, u32 index, u32 len, typedef int (*leaf_call_t) (struct gfs2_inode *dip, u32 index, u32 len,
u64 leaf_no, void *data); u64 leaf_no, void *data);
typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent, typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent,
......
...@@ -17,22 +17,23 @@ struct inode; ...@@ -17,22 +17,23 @@ struct inode;
struct gfs2_inode; struct gfs2_inode;
struct gfs2_inum; struct gfs2_inum;
struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename); extern struct inode *gfs2_dir_search(struct inode *dir,
int gfs2_dir_check(struct inode *dir, const struct qstr *filename, const struct qstr *filename);
extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
const struct gfs2_inode *ip); const struct gfs2_inode *ip);
int gfs2_dir_add(struct inode *inode, const struct qstr *filename, extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
const struct gfs2_inode *ip, unsigned int type); const struct gfs2_inode *ip, unsigned int type);
int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); extern int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
filldir_t filldir); filldir_t filldir);
int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
const struct gfs2_inode *nip, unsigned int new_type); const struct gfs2_inode *nip, unsigned int new_type);
int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); extern int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
int gfs2_diradd_alloc_required(struct inode *dir, extern int gfs2_diradd_alloc_required(struct inode *dir,
const struct qstr *filename); const struct qstr *filename);
int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, extern int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
struct buffer_head **bhp); struct buffer_head **bhp);
static inline u32 gfs2_disk_hash(const char *data, int len) static inline u32 gfs2_disk_hash(const char *data, int len)
...@@ -61,4 +62,7 @@ static inline void gfs2_qstr2dirent(const struct qstr *name, u16 reclen, struct ...@@ -61,4 +62,7 @@ static inline void gfs2_qstr2dirent(const struct qstr *name, u16 reclen, struct
memcpy(dent + 1, name->name, name->len); memcpy(dent + 1, name->name, name->len);
} }
extern struct qstr gfs2_qdot;
extern struct qstr gfs2_qdotdot;
#endif /* __DIR_DOT_H__ */ #endif /* __DIR_DOT_H__ */
...@@ -126,16 +126,9 @@ static int gfs2_get_name(struct dentry *parent, char *name, ...@@ -126,16 +126,9 @@ static int gfs2_get_name(struct dentry *parent, char *name,
static struct dentry *gfs2_get_parent(struct dentry *child) static struct dentry *gfs2_get_parent(struct dentry *child)
{ {
struct qstr dotdot;
struct dentry *dentry; struct dentry *dentry;
/* dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1));
* XXX(hch): it would be a good idea to keep this around as a
* static variable.
*/
gfs2_str2qstr(&dotdot, "..");
dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &dotdot, 1));
if (!IS_ERR(dentry)) if (!IS_ERR(dentry))
dentry->d_op = &gfs2_dops; dentry->d_op = &gfs2_dops;
return dentry; return dentry;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "glock.h" #include "glock.h"
#include "quota.h" #include "quota.h"
#include "recovery.h" #include "recovery.h"
#include "dir.h"
static struct shrinker qd_shrinker = { static struct shrinker qd_shrinker = {
.shrink = gfs2_shrink_qd_memory, .shrink = gfs2_shrink_qd_memory,
...@@ -78,6 +79,9 @@ static int __init init_gfs2_fs(void) ...@@ -78,6 +79,9 @@ static int __init init_gfs2_fs(void)
{ {
int error; int error;
gfs2_str2qstr(&gfs2_qdot, ".");
gfs2_str2qstr(&gfs2_qdotdot, "..");
error = gfs2_sys_init(); error = gfs2_sys_init();
if (error) if (error)
return error; return error;
......
...@@ -471,18 +471,15 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -471,18 +471,15 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!gfs2_assert_withdraw(sdp, !error)) { if (!gfs2_assert_withdraw(sdp, !error)) {
struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1);
struct qstr str;
gfs2_str2qstr(&str, ".");
gfs2_trans_add_bh(ip->i_gl, dibh, 1); gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent); gfs2_qstr2dirent(&gfs2_qdot, GFS2_DIRENT_SIZE(gfs2_qdot.len), dent);
dent->de_inum = di->di_num; /* already GFS2 endian */ dent->de_inum = di->di_num; /* already GFS2 endian */
dent->de_type = cpu_to_be16(DT_DIR); dent->de_type = cpu_to_be16(DT_DIR);
di->di_entries = cpu_to_be32(1); di->di_entries = cpu_to_be32(1);
gfs2_str2qstr(&str, "..");
dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); gfs2_qstr2dirent(&gfs2_qdotdot, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
gfs2_inum_out(dip, dent); gfs2_inum_out(dip, dent);
dent->de_type = cpu_to_be16(DT_DIR); dent->de_type = cpu_to_be16(DT_DIR);
...@@ -523,7 +520,6 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -523,7 +520,6 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
struct gfs2_inode *ip) struct gfs2_inode *ip)
{ {
struct qstr dotname;
int error; int error;
if (ip->i_entries != 2) { if (ip->i_entries != 2) {
...@@ -540,13 +536,11 @@ static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, ...@@ -540,13 +536,11 @@ static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
if (error) if (error)
return error; return error;
gfs2_str2qstr(&dotname, "."); error = gfs2_dir_del(ip, &gfs2_qdot);
error = gfs2_dir_del(ip, &dotname);
if (error) if (error)
return error; return error;
gfs2_str2qstr(&dotname, ".."); error = gfs2_dir_del(ip, &gfs2_qdotdot);
error = gfs2_dir_del(ip, &dotname);
if (error) if (error)
return error; return error;
...@@ -695,11 +689,8 @@ static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) ...@@ -695,11 +689,8 @@ static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
struct inode *dir = &to->i_inode; struct inode *dir = &to->i_inode;
struct super_block *sb = dir->i_sb; struct super_block *sb = dir->i_sb;
struct inode *tmp; struct inode *tmp;
struct qstr dotdot;
int error = 0; int error = 0;
gfs2_str2qstr(&dotdot, "..");
igrab(dir); igrab(dir);
for (;;) { for (;;) {
...@@ -712,7 +703,7 @@ static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) ...@@ -712,7 +703,7 @@ static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
break; break;
} }
tmp = gfs2_lookupi(dir, &dotdot, 1); tmp = gfs2_lookupi(dir, &gfs2_qdotdot, 1);
if (IS_ERR(tmp)) { if (IS_ERR(tmp)) {
error = PTR_ERR(tmp); error = PTR_ERR(tmp);
break; break;
...@@ -921,9 +912,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, ...@@ -921,9 +912,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
} }
if (dir_rename) { if (dir_rename) {
struct qstr name;
gfs2_str2qstr(&name, "..");
error = gfs2_change_nlink(ndip, +1); error = gfs2_change_nlink(ndip, +1);
if (error) if (error)
goto out_end_trans; goto out_end_trans;
...@@ -931,7 +919,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, ...@@ -931,7 +919,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
if (error) if (error)
goto out_end_trans; goto out_end_trans;
error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR); error = gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR);
if (error) if (error)
goto out_end_trans; goto out_end_trans;
} else { } else {
......
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