summaryrefslogtreecommitdiff
path: root/fs/gfs2/ops_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/ops_file.c')
-rw-r--r--fs/gfs2/ops_file.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 064df8804582..94d76ace0b95 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -177,8 +177,8 @@ static const u32 fsflags_to_gfs2[32] = {
[5] = GFS2_DIF_APPENDONLY,
[7] = GFS2_DIF_NOATIME,
[12] = GFS2_DIF_EXHASH,
- [14] = GFS2_DIF_JDATA,
- [20] = GFS2_DIF_DIRECTIO,
+ [14] = GFS2_DIF_INHERIT_JDATA,
+ [20] = GFS2_DIF_INHERIT_DIRECTIO,
};
static const u32 gfs2_to_fsflags[32] = {
@@ -187,8 +187,6 @@ static const u32 gfs2_to_fsflags[32] = {
[gfs2fl_AppendOnly] = FS_APPEND_FL,
[gfs2fl_NoAtime] = FS_NOATIME_FL,
[gfs2fl_ExHash] = FS_INDEX_FL,
- [gfs2fl_Jdata] = FS_JOURNAL_DATA_FL,
- [gfs2fl_Directio] = FS_DIRECTIO_FL,
[gfs2fl_InheritDirectio] = FS_DIRECTIO_FL,
[gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
};
@@ -207,6 +205,12 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
return error;
fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags);
+ if (!S_ISDIR(inode->i_mode)) {
+ if (ip->i_di.di_flags & GFS2_DIF_JDATA)
+ fsflags |= FS_JOURNAL_DATA_FL;
+ if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO)
+ fsflags |= FS_DIRECTIO_FL;
+ }
if (put_user(fsflags, ptr))
error = -EFAULT;
@@ -270,13 +274,6 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
if ((new_flags ^ flags) == 0)
goto out;
- if (S_ISDIR(inode->i_mode)) {
- if ((new_flags ^ flags) & GFS2_DIF_JDATA)
- new_flags ^= (GFS2_DIF_JDATA|GFS2_DIF_INHERIT_JDATA);
- if ((new_flags ^ flags) & GFS2_DIF_DIRECTIO)
- new_flags ^= (GFS2_DIF_DIRECTIO|GFS2_DIF_INHERIT_DIRECTIO);
- }
-
error = -EINVAL;
if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
goto out;
@@ -315,11 +312,19 @@ out:
static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
{
+ struct inode *inode = filp->f_path.dentry->d_inode;
u32 fsflags, gfsflags;
if (get_user(fsflags, ptr))
return -EFAULT;
gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
- return do_gfs2_set_flags(filp, gfsflags, ~0);
+ if (!S_ISDIR(inode->i_mode)) {
+ if (gfsflags & GFS2_DIF_INHERIT_JDATA)
+ gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA);
+ if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO)
+ gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO);
+ return do_gfs2_set_flags(filp, gfsflags, ~0);
+ }
+ return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
}
static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
@@ -489,6 +494,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 generic_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
@@ -502,7 +530,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))
@@ -557,7 +585,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;
@@ -635,10 +663,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 = {