|
@@ -392,8 +392,8 @@ struct inodes_stat_t {
|
|
#include <linux/semaphore.h>
|
|
#include <linux/semaphore.h>
|
|
#include <linux/fiemap.h>
|
|
#include <linux/fiemap.h>
|
|
#include <linux/rculist_bl.h>
|
|
#include <linux/rculist_bl.h>
|
|
|
|
+#include <linux/atomic.h>
|
|
|
|
|
|
-#include <asm/atomic.h>
|
|
|
|
#include <asm/byteorder.h>
|
|
#include <asm/byteorder.h>
|
|
|
|
|
|
struct export_operations;
|
|
struct export_operations;
|
|
@@ -2195,8 +2195,31 @@ static inline bool execute_ok(struct inode *inode)
|
|
return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
|
|
return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
|
|
}
|
|
}
|
|
|
|
|
|
-extern int get_write_access(struct inode *);
|
|
|
|
-extern int deny_write_access(struct file *);
|
|
|
|
|
|
+/*
|
|
|
|
+ * get_write_access() gets write permission for a file.
|
|
|
|
+ * put_write_access() releases this write permission.
|
|
|
|
+ * This is used for regular files.
|
|
|
|
+ * We cannot support write (and maybe mmap read-write shared) accesses and
|
|
|
|
+ * MAP_DENYWRITE mmappings simultaneously. The i_writecount field of an inode
|
|
|
|
+ * can have the following values:
|
|
|
|
+ * 0: no writers, no VM_DENYWRITE mappings
|
|
|
|
+ * < 0: (-i_writecount) vm_area_structs with VM_DENYWRITE set exist
|
|
|
|
+ * > 0: (i_writecount) users are writing to the file.
|
|
|
|
+ *
|
|
|
|
+ * Normally we operate on that counter with atomic_{inc,dec} and it's safe
|
|
|
|
+ * except for the cases where we don't hold i_writecount yet. Then we need to
|
|
|
|
+ * use {get,deny}_write_access() - these functions check the sign and refuse
|
|
|
|
+ * to do the change if sign is wrong.
|
|
|
|
+ */
|
|
|
|
+static inline int get_write_access(struct inode *inode)
|
|
|
|
+{
|
|
|
|
+ return atomic_inc_unless_negative(&inode->i_writecount) ? 0 : -ETXTBSY;
|
|
|
|
+}
|
|
|
|
+static inline int deny_write_access(struct file *file)
|
|
|
|
+{
|
|
|
|
+ struct inode *inode = file->f_path.dentry->d_inode;
|
|
|
|
+ return atomic_dec_unless_positive(&inode->i_writecount) ? 0 : -ETXTBSY;
|
|
|
|
+}
|
|
static inline void put_write_access(struct inode * inode)
|
|
static inline void put_write_access(struct inode * inode)
|
|
{
|
|
{
|
|
atomic_dec(&inode->i_writecount);
|
|
atomic_dec(&inode->i_writecount);
|