]> err.no Git - linux-2.6/blobdiff - fs/gfs2/ops_file.c
[GFS2] don't call permission()
[linux-2.6] / fs / gfs2 / ops_file.c
index 6f3aeb059c610c58b3f579be055e859cfe4130ba..1737af98a4209bd7a11b11f6539bcd23fd9853b2 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/uio.h>
 #include <linux/blkdev.h>
 #include <linux/mm.h>
+#include <linux/mount.h>
 #include <linux/fs.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/ext2_fs.h>
@@ -30,7 +31,6 @@
 #include "glock.h"
 #include "glops.h"
 #include "inode.h"
-#include "lm.h"
 #include "log.h"
 #include "meta_io.h"
 #include "quota.h"
@@ -38,6 +38,8 @@
 #include "trans.h"
 #include "util.h"
 #include "eaops.h"
+#include "ops_address.h"
+#include "ops_inode.h"
 
 /**
  * gfs2_llseek - seek to a location in a file
@@ -219,10 +221,14 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
        int error;
        u32 new_flags, flags;
 
-       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       error = mnt_want_write(filp->f_path.mnt);
        if (error)
                return error;
 
+       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       if (error)
+               goto out_drop_write;
+
        flags = ip->i_di.di_flags;
        new_flags = (flags & ~mask) | (reqflags & mask);
        if ((new_flags ^ flags) == 0)
@@ -241,11 +247,20 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
            !capable(CAP_LINUX_IMMUTABLE))
                goto out;
        if (!IS_IMMUTABLE(inode)) {
-               error = permission(inode, MAY_WRITE, NULL);
+               error = gfs2_permission(inode, MAY_WRITE);
+               if (error)
+                       goto out;
+       }
+       if ((flags ^ new_flags) & GFS2_DIF_JDATA) {
+               if (flags & GFS2_DIF_JDATA)
+                       gfs2_log_flush(sdp, ip->i_gl);
+               error = filemap_fdatawrite(inode->i_mapping);
+               if (error)
+                       goto out;
+               error = filemap_fdatawait(inode->i_mapping);
                if (error)
                        goto out;
        }
-
        error = gfs2_trans_begin(sdp, RES_DINODE, 0);
        if (error)
                goto out;
@@ -257,10 +272,13 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
        gfs2_dinode_out(ip, bh->b_data);
        brelse(bh);
        gfs2_set_inode_flags(inode);
+       gfs2_set_aops(inode);
 out_trans_end:
        gfs2_trans_end(sdp);
 out:
        gfs2_glock_dq_uninit(&gh);
+out_drop_write:
+       mnt_drop_write(filp->f_path.mnt);
        return error;
 }
 
@@ -312,7 +330,7 @@ static int gfs2_allocate_page_backing(struct page *page)
        do {
                bh.b_state = 0;
                bh.b_size = size;
-               gfs2_block_map(inode, lblock, 1, &bh);
+               gfs2_block_map(inode, lblock, &bh, 1);
                if (!buffer_mapped(&bh))
                        return -EIO;
                size -= bh.b_size;
@@ -353,15 +371,14 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
        ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required);
        if (ret || !alloc_required)
                goto out_unlock;
-
-       ip->i_alloc.al_requested = 0;
+       ret = -ENOMEM;
        al = gfs2_alloc_get(ip);
-       ret = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+       if (al == NULL)
+               goto out_unlock;
+
+       ret = gfs2_quota_lock_check(ip);
        if (ret)
                goto out_alloc_put;
-       ret = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid);
-       if (ret)
-               goto out_quota_unlock;
        al->al_requested = data_blocks + ind_blocks;
        ret = gfs2_inplace_reserve(ip);
        if (ret)
@@ -381,6 +398,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
        last_index = ip->i_inode.i_size >> PAGE_CACHE_SHIFT;
        if (page->index > last_index)
                goto out_unlock_page;
+       ret = 0;
        if (!PageUptodate(page) || page->mapping != ip->i_inode.i_mapping)
                goto out_unlock_page;
        if (gfs2_is_stuffed(ip)) {
@@ -582,6 +600,36 @@ static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
        return generic_setlease(file, arg, fl);
 }
 
+static int gfs2_lm_plock_get(struct gfs2_sbd *sdp, struct lm_lockname *name,
+                     struct file *file, struct file_lock *fl)
+{
+       int error = -EIO;
+       if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+               error = sdp->sd_lockstruct.ls_ops->lm_plock_get(
+                               sdp->sd_lockstruct.ls_lockspace, name, file, fl);
+       return error;
+}
+
+static int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name,
+                 struct file *file, int cmd, struct file_lock *fl)
+{
+       int error = -EIO;
+       if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+               error = sdp->sd_lockstruct.ls_ops->lm_plock(
+                               sdp->sd_lockstruct.ls_lockspace, name, file, cmd, fl);
+       return error;
+}
+
+static int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name,
+                   struct file *file, struct file_lock *fl)
+{
+       int error = -EIO;
+       if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+               error = sdp->sd_lockstruct.ls_ops->lm_punlock(
+                               sdp->sd_lockstruct.ls_lockspace, name, file, fl);
+       return error;
+}
+
 /**
  * gfs2_lock - acquire/release a posix lock on a file
  * @file: the file pointer
@@ -604,15 +652,6 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
        if (__mandatory_lock(&ip->i_inode))
                return -ENOLCK;
 
-       if (sdp->sd_args.ar_localflocks) {
-               if (IS_GETLK(cmd)) {
-                       posix_test_lock(file, fl);
-                       return 0;
-               } else {
-                       return posix_lock_file_wait(file, fl);
-               }
-       }
-
        if (cmd == F_CANCELLK) {
                /* Hack: */
                cmd = F_SETLK;
@@ -637,8 +676,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
        int error = 0;
 
        state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED;
-       flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE 
-               | GL_FLOCK;
+       flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE;
 
        mutex_lock(&fp->f_fl_mutex);
 
@@ -651,9 +689,8 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
                gfs2_glock_dq_wait(fl_gh);
                gfs2_holder_reinit(state, flags, fl_gh);
        } else {
-               error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
-                                     ip->i_no_addr, &gfs2_flock_glops,
-                                     CREATE, &gl);
+               error = gfs2_glock_get(GFS2_SB(&ip->i_inode), ip->i_no_addr,
+                                      &gfs2_flock_glops, CREATE, &gl);
                if (error)
                        goto out;
                gfs2_holder_init(gl, state, flags, fl_gh);
@@ -698,16 +735,12 @@ static void do_unflock(struct file *file, struct file_lock *fl)
 static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
 {
        struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
-       struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
 
        if (!(fl->fl_flags & FL_FLOCK))
                return -ENOLCK;
        if (__mandatory_lock(&ip->i_inode))
                return -ENOLCK;
 
-       if (sdp->sd_args.ar_localflocks)
-               return flock_lock_file_wait(file, fl);
-
        if (fl->fl_type == F_UNLCK) {
                do_unflock(file, fl);
                return 0;
@@ -744,3 +777,27 @@ const struct file_operations gfs2_dir_fops = {
        .flock          = gfs2_flock,
 };
 
+const struct file_operations gfs2_file_fops_nolock = {
+       .llseek         = gfs2_llseek,
+       .read           = do_sync_read,
+       .aio_read       = generic_file_aio_read,
+       .write          = do_sync_write,
+       .aio_write      = generic_file_aio_write,
+       .unlocked_ioctl = gfs2_ioctl,
+       .mmap           = gfs2_mmap,
+       .open           = gfs2_open,
+       .release        = gfs2_close,
+       .fsync          = gfs2_fsync,
+       .splice_read    = generic_file_splice_read,
+       .splice_write   = generic_file_splice_write,
+       .setlease       = gfs2_setlease,
+};
+
+const struct file_operations gfs2_dir_fops_nolock = {
+       .readdir        = gfs2_readdir,
+       .unlocked_ioctl = gfs2_ioctl,
+       .open           = gfs2_open,
+       .release        = gfs2_close,
+       .fsync          = gfs2_fsync,
+};
+