mm: fault feedback #1
[safe/jmp/linux-2.6] / fs / gfs2 / ops_file.c
index faa07e4..1a5e8e8 100644 (file)
@@ -7,7 +7,6 @@
  * of the GNU General Public License version 2.
  */
 
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -16,7 +15,6 @@
 #include <linux/uio.h>
 #include <linux/blkdev.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/ext2_fs.h>
 #include "util.h"
 #include "eaops.h"
 
-/* For regular, non-NFS */
-struct filldir_reg {
-       struct gfs2_sbd *fdr_sbd;
-       int fdr_prefetch;
-
-       filldir_t fdr_filldir;
-       void *fdr_opaque;
-};
-
 /*
  * Most fields left uninitialised to catch anybody who tries to
  * use them. f_flags set to prevent file_accessed() from touching
@@ -128,41 +117,6 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
 }
 
 /**
- * filldir_func - Report a directory entry to the caller of gfs2_dir_read()
- * @opaque: opaque data used by the function
- * @name: the name of the directory entry
- * @length: the length of the name
- * @offset: the entry's offset in the directory
- * @inum: the inode number the entry points to
- * @type: the type of inode the entry points to
- *
- * Returns: 0 on success, 1 if buffer full
- */
-
-static int filldir_func(void *opaque, const char *name, unsigned int length,
-                       u64 offset, struct gfs2_inum_host *inum,
-                       unsigned int type)
-{
-       struct filldir_reg *fdr = (struct filldir_reg *)opaque;
-       struct gfs2_sbd *sdp = fdr->fdr_sbd;
-       int error;
-
-       error = fdr->fdr_filldir(fdr->fdr_opaque, name, length, offset,
-                                inum->no_addr, type);
-       if (error)
-               return 1;
-
-       if (fdr->fdr_prefetch && !(length == 1 && *name == '.')) {
-               gfs2_glock_prefetch_num(sdp, inum->no_addr, &gfs2_inode_glops,
-                                      LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY);
-               gfs2_glock_prefetch_num(sdp, inum->no_addr, &gfs2_iopen_glops,
-                                      LM_ST_SHARED, LM_FLAG_TRY);
-       }
-
-       return 0;
-}
-
-/**
  * gfs2_readdir - Read directory entries from a directory
  * @file: The directory to read from
  * @dirent: Buffer for dirents
@@ -175,16 +129,10 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
 {
        struct inode *dir = file->f_mapping->host;
        struct gfs2_inode *dip = GFS2_I(dir);
-       struct filldir_reg fdr;
        struct gfs2_holder d_gh;
        u64 offset = file->f_pos;
        int error;
 
-       fdr.fdr_sbd = GFS2_SB(dir);
-       fdr.fdr_prefetch = 1;
-       fdr.fdr_filldir = filldir;
-       fdr.fdr_opaque = dirent;
-
        gfs2_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh);
        error = gfs2_glock_nq_atime(&d_gh);
        if (error) {
@@ -192,7 +140,7 @@ static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
                return error;
        }
 
-       error = gfs2_dir_read(dir, &offset, &fdr, filldir_func);
+       error = gfs2_dir_read(dir, &offset, dirent, filldir);
 
        gfs2_glock_dq_uninit(&d_gh);
 
@@ -541,6 +489,29 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
 }
 
 /**
+ * gfs2_setlease - acquire/release a file lease
+ * @file: the file pointer
+ * @arg: lease type
+ * @fl: file lock
+ *
+ * Returns: errno
+ */
+
+static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
+
+       /*
+        * We don't currently have a way to enforce a lease across the whole
+        * cluster; until we do, disable leases (by just returning -EINVAL),
+        * unless the administrator has requested purely local locking.
+        */
+       if (!sdp->sd_args.ar_localflocks)
+               return -EINVAL;
+       return setlease(file, arg, fl);
+}
+
+/**
  * gfs2_lock - acquire/release a posix lock on a file
  * @file: the file pointer
  * @cmd: either modify or retrieve lock state, possibly wait
@@ -554,7 +525,7 @@ static int gfs2_lock(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);
        struct lm_lockname name =
-               { .ln_number = ip->i_num.no_addr,
+               { .ln_number = ip->i_no_addr,
                  .ln_type = LM_TYPE_PLOCK };
 
        if (!(fl->fl_flags & FL_POSIX))
@@ -564,18 +535,18 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
 
        if (sdp->sd_args.ar_localflocks) {
                if (IS_GETLK(cmd)) {
-                       struct file_lock tmp;
-                       int ret;
-                       ret = posix_test_lock(file, fl, &tmp);
-                       fl->fl_type = F_UNLCK;
-                       if (ret)
-                               memcpy(fl, &tmp, sizeof(struct file_lock));
+                       posix_test_lock(file, fl);
                        return 0;
                } else {
                        return posix_lock_file_wait(file, fl);
                }
        }
 
+       if (cmd == F_CANCELLK) {
+               /* Hack: */
+               cmd = F_SETLK;
+               fl->fl_type = F_UNLCK;
+       }
        if (IS_GETLK(cmd))
                return gfs2_lm_plock_get(sdp, &name, file, fl);
        else if (fl->fl_type == F_UNLCK)
@@ -609,7 +580,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl)
                gfs2_glock_dq_uninit(fl_gh);
        } else {
                error = gfs2_glock_get(GFS2_SB(&ip->i_inode),
-                                     ip->i_num.no_addr, &gfs2_flock_glops,
+                                     ip->i_no_addr, &gfs2_flock_glops,
                                      CREATE, &gl);
                if (error)
                        goto out;
@@ -687,10 +658,10 @@ const struct file_operations gfs2_file_fops = {
        .release        = gfs2_close,
        .fsync          = gfs2_fsync,
        .lock           = gfs2_lock,
-       .sendfile       = generic_file_sendfile,
        .flock          = gfs2_flock,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
+       .setlease       = gfs2_setlease,
 };
 
 const struct file_operations gfs2_dir_fops = {