To avoid duplication and simplify implementation, we remove gfs2 lock
method (gfs2_lock and gfs2_flock) from file operation table for
lock_nolock protocol. This would allow VFS layer to handle posix and
flock logics like any other in-tree filesystem. The existing
implementation has few issues that would fail NFS connectathon test
(cthon04).
-- Wendy
GFS2 supports two modes of locking - lock_nolock for single node filesystem
and lock_dlm for cluster mode locking. The gfs2 lock methods are removed from
file operation table for lock_nolock protocol. This would allow VFS to handle
posix lock and flock logics just like other in-tree filesystems without
duplication.
Signed-off-by: S. Wendy Cheng <[EMAIL PROTECTED]>
inode.c | 11 +++++++++--
ops_file.c | 39 ++++++++++++++++++++++++++-------------
ops_file.h | 2 ++
3 files changed, 37 insertions(+), 15 deletions(-)
--- e58-o/fs/gfs2/ops_file.h 2007-11-28 10:50:58.000000000 -0500
+++ e58/fs/gfs2/ops_file.h 2007-11-28 17:03:48.000000000 -0500
@@ -20,5 +20,7 @@ extern int gfs2_internal_read(struct gfs
extern void gfs2_set_inode_flags(struct inode *inode);
extern const struct file_operations gfs2_file_fops;
extern const struct file_operations gfs2_dir_fops;
+extern const struct file_operations gfs2_file_fops_nolock;
+extern const struct file_operations gfs2_dir_fops_nolock;
#endif /* __OPS_FILE_DOT_H__ */
--- e58-o/fs/gfs2/ops_file.c 2007-11-28 10:51:10.000000000 -0500
+++ e58/fs/gfs2/ops_file.c 2007-11-28 17:11:48.000000000 -0500
@@ -528,15 +528,6 @@ static int gfs2_lock(struct file *file,
if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
return -ENOLCK;
- if (sdp->sd_args.ar_localflocks) {
- if (IS_GETLK(cmd)) {
- posix_test_lock(file, fl, NULL);
- return 0;
- } else {
- return posix_lock_file_wait(file, fl);
- }
- }
-
if (cmd == F_CANCELLK) {
/* Hack: */
cmd = F_SETLK;
@@ -622,16 +613,12 @@ static void do_unflock(struct file *file
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 ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
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;
@@ -669,3 +656,29 @@ const struct file_operations gfs2_dir_fo
.flock = gfs2_flock,
};
+const struct file_operations gfs2_file_fops_nolock = {
+ .llseek = gfs2_llseek,
+ .read = generic_file_read,
+ .readv = generic_file_readv,
+ .aio_read = generic_file_aio_read,
+ .write = generic_file_write,
+ .writev = generic_file_writev,
+ .aio_write = generic_file_aio_write,
+ .unlocked_ioctl = gfs2_ioctl,
+ .mmap = gfs2_mmap,
+ .open = gfs2_open,
+ .release = gfs2_close,
+ .fsync = gfs2_fsync,
+ .sendfile = generic_file_sendfile,
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+};
+
+const struct file_operations gfs2_dir_fops_nolock = {
+ .readdir = gfs2_readdir,
+ .unlocked_ioctl = gfs2_ioctl,
+ .open = gfs2_open,
+ .release = gfs2_close,
+ .fsync = gfs2_fsync,
+};
+
--- e58-o/fs/gfs2/inode.c 2007-11-28 10:51:10.000000000 -0500
+++ e58/fs/gfs2/inode.c 2007-11-28 17:11:13.000000000 -0500
@@ -132,14 +132,21 @@ static struct inode *gfs2_iget_skip(stru
void gfs2_set_iop(struct inode *inode)
{
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
umode_t mode = inode->i_mode;
if (S_ISREG(mode)) {
inode->i_op = &gfs2_file_iops;
- inode->i_fop = &gfs2_file_fops;
+ if (sdp->sd_args.ar_localflocks)
+ inode->i_fop = &gfs2_file_fops_nolock;
+ else
+ inode->i_fop = &gfs2_file_fops;
} else if (S_ISDIR(mode)) {
inode->i_op = &gfs2_dir_iops;
- inode->i_fop = &gfs2_dir_fops;
+ if (sdp->sd_args.ar_localflocks)
+ inode->i_fop = &gfs2_dir_fops_nolock;
+ else
+ inode->i_fop = &gfs2_dir_fops;
} else if (S_ISLNK(mode)) {
inode->i_op = &gfs2_symlink_iops;
} else {