]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/gfs2/inode.c
[GFS2] Change argument to gfs2_dinode_print
[linux-2.6-omap-h63xx.git] / fs / gfs2 / inode.c
index 81a92116594133e8a0613fb9425955a1657f37e5..4c5d286fefdb91f9537a04d8173be061e922ced8 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/crc32.h>
 #include <linux/lm_interface.h>
+#include <linux/security.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -47,7 +48,7 @@
 void gfs2_inode_attr_in(struct gfs2_inode *ip)
 {
        struct inode *inode = &ip->i_inode;
-       struct gfs2_dinode *di = &ip->i_di;
+       struct gfs2_dinode_host *di = &ip->i_di;
 
        inode->i_ino = ip->i_num.no_addr;
 
@@ -97,7 +98,7 @@ void gfs2_inode_attr_in(struct gfs2_inode *ip)
 void gfs2_inode_attr_out(struct gfs2_inode *ip)
 {
        struct inode *inode = &ip->i_inode;
-       struct gfs2_dinode *di = &ip->i_di;
+       struct gfs2_dinode_host *di = &ip->i_di;
        gfs2_assert_withdraw(GFS2_SB(inode),
                (di->di_mode & S_IFMT) == (inode->i_mode & S_IFMT));
        di->di_mode = inode->i_mode;
@@ -111,7 +112,7 @@ void gfs2_inode_attr_out(struct gfs2_inode *ip)
 static int iget_test(struct inode *inode, void *opaque)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_inum *inum = opaque;
+       struct gfs2_inum_host *inum = opaque;
 
        if (ip && ip->i_num.no_addr == inum->no_addr)
                return 1;
@@ -122,19 +123,19 @@ static int iget_test(struct inode *inode, void *opaque)
 static int iget_set(struct inode *inode, void *opaque)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_inum *inum = opaque;
+       struct gfs2_inum_host *inum = opaque;
 
        ip->i_num = *inum;
        return 0;
 }
 
-struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum)
+struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum)
 {
        return ilookup5(sb, (unsigned long)inum->no_formal_ino,
                        iget_test, inum);
 }
 
-static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
+static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum)
 {
        return iget5_locked(sb, (unsigned long)inum->no_formal_ino,
                     iget_test, iget_set, inum);
@@ -149,13 +150,16 @@ static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum)
  * Returns: A VFS inode, or an error
  */
 
-struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned int type)
+struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type)
 {
        struct inode *inode = gfs2_iget(sb, inum);
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_glock *io_gl;
        int error;
 
+       if (!inode)
+               return ERR_PTR(-ENOBUFS);
+
        if (inode->i_state & I_NEW) {
                struct gfs2_sbd *sdp = GFS2_SB(inode);
                umode_t mode = DT2IF(type);
@@ -204,6 +208,40 @@ fail:
        return ERR_PTR(error);
 }
 
+static void gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+{
+       struct gfs2_dinode_host *di = &ip->i_di;
+       const struct gfs2_dinode *str = buf;
+
+       gfs2_meta_header_in(&di->di_header, buf);
+       gfs2_inum_in(&di->di_num, &str->di_num);
+
+       di->di_mode = be32_to_cpu(str->di_mode);
+       di->di_uid = be32_to_cpu(str->di_uid);
+       di->di_gid = be32_to_cpu(str->di_gid);
+       di->di_nlink = be32_to_cpu(str->di_nlink);
+       di->di_size = be64_to_cpu(str->di_size);
+       di->di_blocks = be64_to_cpu(str->di_blocks);
+       di->di_atime = be64_to_cpu(str->di_atime);
+       di->di_mtime = be64_to_cpu(str->di_mtime);
+       di->di_ctime = be64_to_cpu(str->di_ctime);
+       di->di_major = be32_to_cpu(str->di_major);
+       di->di_minor = be32_to_cpu(str->di_minor);
+
+       di->di_goal_meta = be64_to_cpu(str->di_goal_meta);
+       di->di_goal_data = be64_to_cpu(str->di_goal_data);
+       di->di_generation = be64_to_cpu(str->di_generation);
+
+       di->di_flags = be32_to_cpu(str->di_flags);
+       di->di_payload_format = be32_to_cpu(str->di_payload_format);
+       di->di_height = be16_to_cpu(str->di_height);
+
+       di->di_depth = be16_to_cpu(str->di_depth);
+       di->di_entries = be32_to_cpu(str->di_entries);
+
+       di->di_eattr = be64_to_cpu(str->di_eattr);
+}
+
 /**
  * gfs2_inode_refresh - Refresh the incore copy of the dinode
  * @ip: The GFS2 inode
@@ -225,13 +263,13 @@ int gfs2_inode_refresh(struct gfs2_inode *ip)
                return -EIO;
        }
 
-       gfs2_dinode_in(&ip->i_di, dibh->b_data);
+       gfs2_dinode_in(ip, dibh->b_data);
 
        brelse(dibh);
 
        if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) {
                if (gfs2_consist_inode(ip))
-                       gfs2_dinode_print(&ip->i_di);
+                       gfs2_dinode_print(ip);
                return -EIO;
        }
        if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino)
@@ -251,7 +289,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip)
 
        if (ip->i_di.di_blocks != 1) {
                if (gfs2_consist_inode(ip))
-                       gfs2_dinode_print(&ip->i_di);
+                       gfs2_dinode_print(ip);
                return -EIO;
        }
 
@@ -321,7 +359,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
           bigger than the old one, we must have underflowed. */
        if (diff < 0 && nlink > ip->i_di.di_nlink) {
                if (gfs2_consist_inode(ip))
-                       gfs2_dinode_print(&ip->i_di);
+                       gfs2_dinode_print(ip);
                return -EIO;
        }
 
@@ -334,7 +372,7 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
        ip->i_inode.i_nlink = nlink;
 
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-       gfs2_dinode_out(&ip->i_di, dibh->b_data);
+       gfs2_dinode_out(ip, dibh->b_data);
        brelse(dibh);
        mark_inode_dirty(&ip->i_inode);
 
@@ -390,7 +428,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
        struct super_block *sb = dir->i_sb;
        struct gfs2_inode *dip = GFS2_I(dir);
        struct gfs2_holder d_gh;
-       struct gfs2_inum inum;
+       struct gfs2_inum_host inum;
        unsigned int type;
        int error = 0;
        struct inode *inode = NULL;
@@ -432,7 +470,7 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino)
 {
        struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
        struct buffer_head *bh;
-       struct gfs2_inum_range ir;
+       struct gfs2_inum_range_host ir;
        int error;
 
        error = gfs2_trans_begin(sdp, RES_DINODE, 0);
@@ -475,7 +513,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino)
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode);
        struct gfs2_holder gh;
        struct buffer_head *bh;
-       struct gfs2_inum_range ir;
+       struct gfs2_inum_range_host ir;
        int error;
 
        error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
@@ -496,21 +534,22 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino)
        if (!ir.ir_length) {
                struct buffer_head *m_bh;
                u64 x, y;
+               __be64 z;
 
                error = gfs2_meta_inode_buffer(m_ip, &m_bh);
                if (error)
                        goto out_brelse;
 
-               x = *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode));
-               x = y = be64_to_cpu(x);
+               z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode));
+               x = y = be64_to_cpu(z);
                ir.ir_start = x;
                ir.ir_length = GFS2_INUM_QUANTUM;
                x += GFS2_INUM_QUANTUM;
                if (x < y)
                        gfs2_consist_inode(m_ip);
-               x = cpu_to_be64(x);
+               z = cpu_to_be64(x);
                gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
-               *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x;
+               *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z;
 
                brelse(m_bh);
        }
@@ -606,7 +645,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
                *gid = current->fsgid;
 }
 
-static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum,
+static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum,
                        u64 *generation)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
@@ -646,7 +685,7 @@ out:
  */
 
 static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
-                       const struct gfs2_inum *inum, unsigned int mode,
+                       const struct gfs2_inum_host *inum, unsigned int mode,
                        unsigned int uid, unsigned int gid,
                        const u64 *generation)
 {
@@ -703,7 +742,7 @@ static void init_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 *inum,
+                      unsigned int mode, const struct gfs2_inum_host *inum,
                       const u64 *generation)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
@@ -787,7 +826,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
                goto fail_end_trans;
        ip->i_di.di_nlink = 1;
        gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-       gfs2_dinode_out(&ip->i_di, dibh->b_data);
+       gfs2_dinode_out(ip, dibh->b_data);
        brelse(dibh);
        return 0;
 
@@ -806,6 +845,39 @@ fail:
        return error;
 }
 
+static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
+{
+       int err;
+       size_t len;
+       void *value;
+       char *name;
+       struct gfs2_ea_request er;
+
+       err = security_inode_init_security(&ip->i_inode, &dip->i_inode,
+                                          &name, &value, &len);
+
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       return 0;
+               return err;
+       }
+
+       memset(&er, 0, sizeof(struct gfs2_ea_request));
+
+       er.er_type = GFS2_EATYPE_SECURITY;
+       er.er_name = name;
+       er.er_data = value;
+       er.er_name_len = strlen(name);
+       er.er_data_len = len;
+
+       err = gfs2_ea_set_i(ip, &er);
+
+       kfree(value);
+       kfree(name);
+
+       return err;
+}
+
 /**
  * gfs2_createi - Create a new inode
  * @ghs: An array of two holders
@@ -829,7 +901,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        struct gfs2_inode *dip = ghs->gh_gl->gl_object;
        struct inode *dir = &dip->i_inode;
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
-       struct gfs2_inum inum;
+       struct gfs2_inum_host inum;
        int error;
        u64 generation;
 
@@ -897,6 +969,10 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_iput;
 
+       error = gfs2_security_init(dip, GFS2_I(inode));
+       if (error)
+               goto fail_iput;
+
        error = link_dinode(dip, name, GFS2_I(inode));
        if (error)
                goto fail_iput;
@@ -934,7 +1010,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
 
        if (ip->i_di.di_entries != 2) {
                if (gfs2_consist_inode(ip))
-                       gfs2_dinode_print(&ip->i_di);
+                       gfs2_dinode_print(ip);
                return -EIO;
        }
 
@@ -977,7 +1053,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
 int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
                   struct gfs2_inode *ip)
 {
-       struct gfs2_inum inum;
+       struct gfs2_inum_host inum;
        unsigned int type;
        int error;
 
@@ -1307,7 +1383,7 @@ __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
                gfs2_inode_attr_out(ip);
 
                gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-               gfs2_dinode_out(&ip->i_di, dibh->b_data);
+               gfs2_dinode_out(ip, dibh->b_data);
                brelse(dibh);
        }
        return error;