]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Remove fcntl f_op
authorMatthew Wilcox <willy@debian.org>
Fri, 13 Aug 2004 02:48:04 +0000 (19:48 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 13 Aug 2004 02:48:04 +0000 (19:48 -0700)
The newly introduced ->fcntl file_operation is badly thought out,
not to mention undocumented.  This patch replaces it with two better
defined operations -- check_flags and dir_notify.  Any other fcntl()s
that filesystems are interested in can have their own properly typed
f_op method when they need it.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Documentation/filesystems/Locking
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/fcntl.c
fs/dnotify.c
fs/fcntl.c
fs/nfs/file.c
include/linux/fs.h

index e0ef1f80f4f31d667ce373e2be179154da141b73..1c465edd2bbd670a1e86cd29973fed6f25105a81 100644 (file)
@@ -349,6 +349,8 @@ prototypes:
                        loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *, unsigned long,
                        unsigned long, unsigned long, unsigned long);
+       int (*check_flags)(int);
+       int (*dir_notify)(struct file *, unsigned long);
 };
 
 locking rules:
@@ -375,6 +377,8 @@ writev:                     no
 sendfile:              no
 sendpage:              no
 get_unmapped_area:     no
+check_flags:           no
+dir_notify:            no
 
 ->llseek() locking has moved from llseek to the individual llseek
 implementations.  If your fs is not using generic_file_llseek, you
index 2607ce38a697a0815f167525acd74350754c75d8..fbc737e2eeb339c3b8bd792b3bc6a0cb28a25d15 100644 (file)
@@ -534,18 +534,14 @@ struct file_operations cifs_file_ops = {
        .flush = cifs_flush,
        .mmap  = cifs_file_mmap,
        .sendfile = generic_file_sendfile,
-#ifdef CONFIG_CIFS_FCNTL
-       .fcntl = cifs_fcntl,
-#endif
+       .dir_notify = cifs_dir_notify,
 };
 
 struct file_operations cifs_dir_ops = {
        .readdir = cifs_readdir,
        .release = cifs_closedir,
        .read    = generic_read_dir,
-#ifdef CONFIG_CIFS_FCNTL
-       .fcntl   = cifs_fcntl,
-#endif
+       .dir_notify = cifs_dir_notify,
 };
 
 static void
index 258442eea695c0944826f75882cd535b5bda1ce6..866b68c8beeb312b07e3fe19ba75771d2d4fe296 100644 (file)
@@ -74,7 +74,7 @@ extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
 extern struct file_operations cifs_dir_ops;
 extern int cifs_dir_open(struct inode *inode, struct file *file);
 extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
-extern long cifs_fcntl(int, unsigned int, unsigned long, struct file *);
+extern int cifs_dir_notify(struct file *, unsigned long arg);
 
 /* Functions related to dir entries */
 extern struct dentry_operations cifs_dentry_ops;
index 1469a406f6ad594898feeb8439fb148c70bbab07..b908768b62159c922f2711dba82b651b19afc7ad 100644 (file)
@@ -28,7 +28,7 @@
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
 
-int cifs_directory_notify(unsigned long arg, struct file * file)
+int cifs_dir_notify(struct file * file, unsigned long arg)
 {
        int xid;
        int rc = -EINVAL;
@@ -70,53 +70,3 @@ int cifs_directory_notify(unsigned long arg, struct file * file)
        FreeXid(xid);
        return rc;
 }
-
-
-long cifs_fcntl(int file_desc, unsigned int command, unsigned long arg,
-                               struct file * file)
-{
-       /* Few few file control functions need to be specially mapped. So far
-       only:
-               F_NOTIFY (for directory change notification)
-       And eventually:
-               F_GETLEASE
-               F_SETLEASE 
-       need to be mapped here. The others either already are mapped downstream
-       or do not need to go to the server (client only sideeffects):
-               F_DUPFD:
-               F_GETFD:
-               F_SETFD:
-               F_GETFL:
-               F_SETFL:
-               F_GETLK:
-               F_SETLK:
-               F_SETLKW:
-               F_GETOWN:
-               F_SETOWN:
-               F_GETSIG:
-               F_SETSIG:
-       */
-       long rc = 0;
-
-       cFYI(1,("cifs_fcntl: command %d with arg %lx",command,arg)); /* BB removeme BB */
-
-       switch (command) {
-       case F_NOTIFY:
-               /* let the local call have a chance to fail first */
-               rc = generic_file_fcntl(file_desc,command,arg,file);
-               if(rc)
-                       return rc;
-               else {
-                       /* local call succeeded try to do remote notify to
-                       pick up changes from other clients to server file */
-                       cifs_directory_notify(arg, file);
-                       /* BB add case to long and return rc from above */
-                       return rc;
-               }
-               break;
-       default:
-               break;
-       }
-       return generic_file_fcntl(file_desc,command,arg,file);
-}
-                
index 2801eb4fdf1016b6115d3e7a020f45c97bb4a00c..f3b540dd5d11712b5aa7631084ce4f3303ec21b0 100644 (file)
@@ -104,6 +104,9 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
        dn->dn_next = inode->i_dnotify;
        inode->i_dnotify = dn;
        spin_unlock(&inode->i_lock);
+
+       if (filp->f_op && filp->f_op->dir_notify)
+               return filp->f_op->dir_notify(filp, arg);
        return 0;
 
 out_free:
index 77cec9debe17860a97999c7bd40fcd5861a09a23..305abb43d0c02b1781be5085316e5759b2432a52 100644 (file)
@@ -239,6 +239,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
                                return -EINVAL;
        }
 
+       if (filp->f_op && filp->f_op->check_flags)
+               error = filp->f_op->check_flags(arg);
+       if (error)
+               return error;
+
        lock_kernel();
        if ((arg ^ filp->f_flags) & FASYNC) {
                if (filp->f_op && filp->f_op->fasync) {
@@ -287,8 +292,8 @@ void f_delown(struct file *filp)
 
 EXPORT_SYMBOL(f_delown);
 
-long generic_file_fcntl(int fd, unsigned int cmd,
-                       unsigned long arg, struct file *filp)
+static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
+               struct file *filp)
 {
        long err = -EINVAL;
 
@@ -356,15 +361,6 @@ long generic_file_fcntl(int fd, unsigned int cmd,
        }
        return err;
 }
-EXPORT_SYMBOL(generic_file_fcntl);
-
-static long do_fcntl(int fd, unsigned int cmd,
-                       unsigned long arg, struct file *filp)
-{
-       if (filp->f_op && filp->f_op->fcntl)
-               return filp->f_op->fcntl(fd, cmd, arg, filp);
-       return generic_file_fcntl(fd, cmd, arg, filp);
-}
 
 asmlinkage long sys_fcntl(int fd, unsigned int cmd, unsigned long arg)
 {      
index 02deae074c6f54d73b0e0f9daa7ed7c09770c72d..ee2addb5c4493bcb11250f8a817cfd361ca843be 100644 (file)
@@ -33,8 +33,6 @@
 
 #define NFSDBG_FACILITY                NFSDBG_FILE
 
-static long nfs_file_fcntl(int fd, unsigned int cmd,
-                       unsigned long arg, struct file *filp);
 static int nfs_file_open(struct inode *, struct file *);
 static int nfs_file_release(struct inode *, struct file *);
 static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
@@ -43,6 +41,7 @@ static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
 static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t);
 static int  nfs_file_flush(struct file *);
 static int  nfs_fsync(struct file *, struct dentry *dentry, int datasync);
+static int nfs_check_flags(int flags);
 
 struct file_operations nfs_file_operations = {
        .llseek         = remote_llseek,
@@ -57,7 +56,7 @@ struct file_operations nfs_file_operations = {
        .fsync          = nfs_fsync,
        .lock           = nfs_lock,
        .sendfile       = nfs_file_sendfile,
-       .fcntl          = nfs_file_fcntl,
+       .check_flags    = nfs_check_flags,
 };
 
 struct inode_operations nfs_file_inode_operations = {
@@ -71,26 +70,12 @@ struct inode_operations nfs_file_inode_operations = {
 # define IS_SWAPFILE(inode)    (0)
 #endif
 
-#define nfs_invalid_flags      (O_APPEND | O_DIRECT)
-
-/*
- * Check for special cases that NFS doesn't support, and
- * pass the rest to the generic fcntl function.
- */
-static long
-nfs_file_fcntl(int fd, unsigned int cmd,
-               unsigned long arg, struct file *filp)
+static int nfs_check_flags(int flags)
 {
-       switch (cmd) {
-       case F_SETFL:
-               if ((filp->f_flags & nfs_invalid_flags) == nfs_invalid_flags)
-                       return -EINVAL;
-               break;
-       default:
-               break;
-       }
+       if (flags & (O_APPEND | O_DIRECT))
+               return -EINVAL;
 
-       return generic_file_fcntl(fd, cmd, arg, filp);
+       return 0;
 }
 
 /*
@@ -101,10 +86,11 @@ nfs_file_open(struct inode *inode, struct file *filp)
 {
        struct nfs_server *server = NFS_SERVER(inode);
        int (*open)(struct inode *, struct file *);
-       int res = 0;
+       int res;
 
-       if ((filp->f_flags & nfs_invalid_flags) == nfs_invalid_flags)
-               return -EINVAL;
+       res = nfs_check_flags(filp->f_flags);
+       if (!res)
+               return res;
 
        lock_kernel();
        /* Do NFSv4 open() call */
index e6f97b00fe34d5fa0b49831aee76d41e574d64bf..7e10a252a7d17553c51a23af0336ed35afbf2edf 100644 (file)
@@ -665,9 +665,6 @@ extern struct list_head file_lock_list;
 
 #include <linux/fcntl.h>
 
-extern long generic_file_fcntl(int fd, unsigned int cmd,
-                               unsigned long arg, struct file *filp);
-
 extern int fcntl_getlk(struct file *, struct flock __user *);
 extern int fcntl_setlk(struct file *, unsigned int, struct flock __user *);
 
@@ -895,8 +892,8 @@ struct file_operations {
        ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
        ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
-       long (*fcntl)(int fd, unsigned int cmd,
-                       unsigned long arg, struct file *filp);
+       int (*check_flags)(int);
+       int (*dir_notify)(struct file *filp, unsigned long arg);
 };
 
 struct inode_operations {