diff options
Diffstat (limited to 'fs/smb/client/cifsglob.h')
| -rw-r--r-- | fs/smb/client/cifsglob.h | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 080ea601c209..709e96e07791 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -20,6 +20,7 @@ #include <linux/utsname.h> #include <linux/sched/mm.h> #include <linux/netfs.h> +#include <linux/fcntl.h> #include "cifs_fs_sb.h" #include "cifsacl.h" #include <crypto/internal/hash.h> @@ -1580,24 +1581,59 @@ CIFS_I(struct inode *inode) return container_of(inode, struct cifsInodeInfo, netfs.inode); } -static inline struct cifs_sb_info * -CIFS_SB(struct super_block *sb) +static inline void *cinode_to_fsinfo(struct cifsInodeInfo *cinode) +{ + return cinode->netfs.inode.i_sb->s_fs_info; +} + +static inline void *super_to_fsinfo(struct super_block *sb) { return sb->s_fs_info; } -static inline struct cifs_sb_info * -CIFS_FILE_SB(struct file *file) +static inline void *inode_to_fsinfo(struct inode *inode) +{ + return inode->i_sb->s_fs_info; +} + +static inline void *file_to_fsinfo(struct file *file) +{ + return file_inode(file)->i_sb->s_fs_info; +} + +static inline void *dentry_to_fsinfo(struct dentry *dentry) +{ + return dentry->d_sb->s_fs_info; +} + +static inline void *const_dentry_to_fsinfo(const struct dentry *dentry) +{ + return dentry->d_sb->s_fs_info; +} + +#define CIFS_SB(_ptr) \ + ((struct cifs_sb_info *) \ + _Generic((_ptr), \ + struct cifsInodeInfo * : cinode_to_fsinfo, \ + const struct dentry * : const_dentry_to_fsinfo, \ + struct super_block * : super_to_fsinfo, \ + struct dentry * : dentry_to_fsinfo, \ + struct inode * : inode_to_fsinfo, \ + struct file * : file_to_fsinfo)(_ptr)) + +/* + * Use atomic_t for @cifs_sb->mnt_cifs_flags as it is currently accessed + * locklessly and may be changed concurrently by mount/remount and reconnect + * paths. + */ +static inline unsigned int cifs_sb_flags(const struct cifs_sb_info *cifs_sb) { - return CIFS_SB(file_inode(file)->i_sb); + return atomic_read(&cifs_sb->mnt_cifs_flags); } static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) - return '/'; - else - return '\\'; + return (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS) ? '/' : '\\'; } static inline void @@ -1849,12 +1885,12 @@ static inline bool is_replayable_error(int error) } -/* cifs_get_writable_file() flags */ -enum cifs_writable_file_flags { - FIND_WR_ANY = 0U, - FIND_WR_FSUID_ONLY = (1U << 0), - FIND_WR_WITH_DELETE = (1U << 1), - FIND_WR_NO_PENDING_DELETE = (1U << 2), +enum cifs_find_flags { + FIND_ANY = 0U, + FIND_FSUID_ONLY = (1U << 0), + FIND_WITH_DELETE = (1U << 1), + FIND_NO_PENDING_DELETE = (1U << 2), + FIND_OPEN_FLAGS = (1U << 3), }; #define MID_FREE 0 @@ -2314,9 +2350,8 @@ static inline bool __cifs_cache_state_check(struct cifsInodeInfo *cinode, unsigned int oplock_flags, unsigned int sb_flags) { - struct cifs_sb_info *cifs_sb = CIFS_SB(cinode->netfs.inode.i_sb); + unsigned int sflags = cifs_sb_flags(CIFS_SB(cinode)); unsigned int oplock = READ_ONCE(cinode->oplock); - unsigned int sflags = cifs_sb->mnt_cifs_flags; return (oplock & oplock_flags) || (sflags & sb_flags); } @@ -2336,4 +2371,25 @@ static inline void cifs_reset_oplock(struct cifsInodeInfo *cinode) WRITE_ONCE(cinode->oplock, 0); } +static inline bool cifs_forced_shutdown(const struct cifs_sb_info *sbi) +{ + return cifs_sb_flags(sbi) & CIFS_MOUNT_SHUTDOWN; +} + +static inline int cifs_open_create_options(unsigned int oflags, int opts) +{ + /* O_SYNC also has bit for O_DSYNC so following check picks up either */ + if (oflags & O_SYNC) + opts |= CREATE_WRITE_THROUGH; + if (oflags & O_DIRECT) + opts |= CREATE_NO_BUFFER; + return opts; +} + +/* + * The number of blocks is not related to (i_size / i_blksize), but instead + * 512 byte (2**9) size is required for calculating num blocks. + */ +#define CIFS_INO_BLOCKS(size) DIV_ROUND_UP_ULL((u64)(size), 512) + #endif /* _CIFS_GLOB_H */ |
