Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifdef pr_fmt
0003 #undef pr_fmt
0004 #endif
0005 
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007 
0008 #include <linux/types.h>
0009 #include <linux/fs.h>
0010 #include <linux/buffer_head.h>
0011 #include "amigaffs.h"
0012 #include <linux/mutex.h>
0013 #include <linux/workqueue.h>
0014 
0015 /* Ugly macros make the code more pretty. */
0016 
0017 #define GET_END_PTR(st,p,sz)         ((st *)((char *)(p)+((sz)-sizeof(st))))
0018 #define AFFS_GET_HASHENTRY(data,hashkey) be32_to_cpu(((struct dir_front *)data)->hashtable[hashkey])
0019 #define AFFS_BLOCK(sb, bh, blk)     (AFFS_HEAD(bh)->table[AFFS_SB(sb)->s_hashsize-1-(blk)])
0020 
0021 #define AFFS_HEAD(bh)       ((struct affs_head *)(bh)->b_data)
0022 #define AFFS_TAIL(sb, bh)   ((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail)))
0023 #define AFFS_ROOT_HEAD(bh)  ((struct affs_root_head *)(bh)->b_data)
0024 #define AFFS_ROOT_TAIL(sb, bh)  ((struct affs_root_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_root_tail)))
0025 #define AFFS_DATA_HEAD(bh)  ((struct affs_data_head *)(bh)->b_data)
0026 #define AFFS_DATA(bh)       (((struct affs_data_head *)(bh)->b_data)->data)
0027 
0028 #define AFFS_CACHE_SIZE     PAGE_SIZE
0029 
0030 #define AFFS_LC_SIZE        (AFFS_CACHE_SIZE/sizeof(u32)/2)
0031 #define AFFS_AC_SIZE        (AFFS_CACHE_SIZE/sizeof(struct affs_ext_key)/2)
0032 #define AFFS_AC_MASK        (AFFS_AC_SIZE-1)
0033 
0034 #define AFFSNAMEMAX 30U
0035 
0036 struct affs_ext_key {
0037     u32 ext;                /* idx of the extended block */
0038     u32 key;                /* block number */
0039 };
0040 
0041 /*
0042  * affs fs inode data in memory
0043  */
0044 struct affs_inode_info {
0045     atomic_t i_opencnt;
0046     struct mutex i_link_lock;       /* Protects internal inode access. */
0047     struct mutex i_ext_lock;        /* Protects internal inode access. */
0048 #define i_hash_lock i_ext_lock
0049     u32  i_blkcnt;          /* block count */
0050     u32  i_extcnt;          /* extended block count */
0051     u32 *i_lc;              /* linear cache of extended blocks */
0052     u32  i_lc_size;
0053     u32  i_lc_shift;
0054     u32  i_lc_mask;
0055     struct affs_ext_key *i_ac;      /* associative cache of extended blocks */
0056     u32  i_ext_last;            /* last accessed extended block */
0057     struct buffer_head *i_ext_bh;       /* bh of last extended block */
0058     loff_t   mmu_private;
0059     u32  i_protect;         /* unused attribute bits */
0060     u32  i_lastalloc;           /* last allocated block */
0061     int  i_pa_cnt;          /* number of preallocated blocks */
0062     struct inode vfs_inode;
0063 };
0064 
0065 /* short cut to get to the affs specific inode data */
0066 static inline struct affs_inode_info *AFFS_I(struct inode *inode)
0067 {
0068     return container_of(inode, struct affs_inode_info, vfs_inode);
0069 }
0070 
0071 /*
0072  * super-block data in memory
0073  *
0074  * Block numbers are adjusted for their actual size
0075  *
0076  */
0077 
0078 struct affs_bm_info {
0079     u32 bm_key;         /* Disk block number */
0080     u32 bm_free;            /* Free blocks in here */
0081 };
0082 
0083 struct affs_sb_info {
0084     int s_partition_size;       /* Partition size in blocks. */
0085     int s_reserved;         /* Number of reserved blocks. */
0086     //u32 s_blksize;            /* Initial device blksize */
0087     u32 s_data_blksize;     /* size of the data block w/o header */
0088     u32 s_root_block;       /* FFS root block number. */
0089     int s_hashsize;         /* Size of hash table. */
0090     unsigned long s_flags;      /* See below. */
0091     kuid_t s_uid;           /* uid to override */
0092     kgid_t s_gid;           /* gid to override */
0093     umode_t s_mode;         /* mode to override */
0094     struct buffer_head *s_root_bh;  /* Cached root block. */
0095     struct mutex s_bmlock;      /* Protects bitmap access. */
0096     struct affs_bm_info *s_bitmap;  /* Bitmap infos. */
0097     u32 s_bmap_count;       /* # of bitmap blocks. */
0098     u32 s_bmap_bits;        /* # of bits in one bitmap blocks */
0099     u32 s_last_bmap;
0100     struct buffer_head *s_bmap_bh;
0101     char *s_prefix;         /* Prefix for volumes and assigns. */
0102     char s_volume[32];      /* Volume prefix for absolute symlinks. */
0103     spinlock_t symlink_lock;    /* protects the previous two */
0104     struct super_block *sb;     /* the VFS superblock object */
0105     int work_queued;        /* non-zero delayed work is queued */
0106     struct delayed_work sb_work;    /* superblock flush delayed work */
0107     spinlock_t work_lock;       /* protects sb_work and work_queued */
0108 };
0109 
0110 #define AFFS_MOUNT_SF_INTL      0x0001 /* International filesystem. */
0111 #define AFFS_MOUNT_SF_BM_VALID      0x0002 /* Bitmap is valid. */
0112 #define AFFS_MOUNT_SF_IMMUTABLE     0x0004 /* Protection bits cannot be changed */
0113 #define AFFS_MOUNT_SF_QUIET     0x0008 /* chmod errors will be not reported */
0114 #define AFFS_MOUNT_SF_SETUID        0x0010 /* Ignore Amiga uid */
0115 #define AFFS_MOUNT_SF_SETGID        0x0020 /* Ignore Amiga gid */
0116 #define AFFS_MOUNT_SF_SETMODE       0x0040 /* Ignore Amiga protection bits */
0117 #define AFFS_MOUNT_SF_MUFS      0x0100 /* Use MUFS uid/gid mapping */
0118 #define AFFS_MOUNT_SF_OFS       0x0200 /* Old filesystem */
0119 #define AFFS_MOUNT_SF_PREFIX        0x0400 /* Buffer for prefix is allocated */
0120 #define AFFS_MOUNT_SF_VERBOSE       0x0800 /* Talk about fs when mounting */
0121 #define AFFS_MOUNT_SF_NO_TRUNCATE   0x1000 /* Don't truncate filenames */
0122 
0123 #define affs_clear_opt(o, opt)    (o &= ~AFFS_MOUNT_##opt)
0124 #define affs_set_opt(o, opt)      (o |= AFFS_MOUNT_##opt)
0125 #define affs_test_opt(o, opt)     ((o) & AFFS_MOUNT_##opt)
0126 
0127 /* short cut to get to the affs specific sb data */
0128 static inline struct affs_sb_info *AFFS_SB(struct super_block *sb)
0129 {
0130     return sb->s_fs_info;
0131 }
0132 
0133 void affs_mark_sb_dirty(struct super_block *sb);
0134 
0135 /* amigaffs.c */
0136 
0137 extern int  affs_insert_hash(struct inode *inode, struct buffer_head *bh);
0138 extern int  affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh);
0139 extern int  affs_remove_header(struct dentry *dentry);
0140 extern u32  affs_checksum_block(struct super_block *sb, struct buffer_head *bh);
0141 extern void affs_fix_checksum(struct super_block *sb, struct buffer_head *bh);
0142 extern void affs_secs_to_datestamp(time64_t secs, struct affs_date *ds);
0143 extern umode_t  affs_prot_to_mode(u32 prot);
0144 extern void affs_mode_to_prot(struct inode *inode);
0145 __printf(3, 4)
0146 extern void affs_error(struct super_block *sb, const char *function,
0147                const char *fmt, ...);
0148 __printf(3, 4)
0149 extern void affs_warning(struct super_block *sb, const char *function,
0150                  const char *fmt, ...);
0151 extern bool affs_nofilenametruncate(const struct dentry *dentry);
0152 extern int  affs_check_name(const unsigned char *name, int len,
0153                 bool notruncate);
0154 extern int  affs_copy_name(unsigned char *bstr, struct dentry *dentry);
0155 
0156 /* bitmap. c */
0157 
0158 extern u32  affs_count_free_blocks(struct super_block *s);
0159 extern void affs_free_block(struct super_block *sb, u32 block);
0160 extern u32  affs_alloc_block(struct inode *inode, u32 goal);
0161 extern int  affs_init_bitmap(struct super_block *sb, int *flags);
0162 extern void affs_free_bitmap(struct super_block *sb);
0163 
0164 /* namei.c */
0165 
0166 extern const struct export_operations affs_export_ops;
0167 extern int  affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
0168 extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int);
0169 extern int  affs_unlink(struct inode *dir, struct dentry *dentry);
0170 extern int  affs_create(struct user_namespace *mnt_userns, struct inode *dir,
0171             struct dentry *dentry, umode_t mode, bool);
0172 extern int  affs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
0173             struct dentry *dentry, umode_t mode);
0174 extern int  affs_rmdir(struct inode *dir, struct dentry *dentry);
0175 extern int  affs_link(struct dentry *olddentry, struct inode *dir,
0176               struct dentry *dentry);
0177 extern int  affs_symlink(struct user_namespace *mnt_userns,
0178             struct inode *dir, struct dentry *dentry,
0179             const char *symname);
0180 extern int  affs_rename2(struct user_namespace *mnt_userns,
0181             struct inode *old_dir, struct dentry *old_dentry,
0182             struct inode *new_dir, struct dentry *new_dentry,
0183             unsigned int flags);
0184 
0185 /* inode.c */
0186 
0187 extern struct inode     *affs_new_inode(struct inode *dir);
0188 extern int           affs_notify_change(struct user_namespace *mnt_userns,
0189                     struct dentry *dentry, struct iattr *attr);
0190 extern void          affs_evict_inode(struct inode *inode);
0191 extern struct inode     *affs_iget(struct super_block *sb,
0192                     unsigned long ino);
0193 extern int           affs_write_inode(struct inode *inode,
0194                     struct writeback_control *wbc);
0195 extern int           affs_add_entry(struct inode *dir, struct inode *inode,
0196                     struct dentry *dentry, s32 type);
0197 
0198 /* file.c */
0199 
0200 void        affs_free_prealloc(struct inode *inode);
0201 extern void affs_truncate(struct inode *);
0202 int     affs_file_fsync(struct file *, loff_t, loff_t, int);
0203 
0204 /* dir.c */
0205 
0206 extern void   affs_dir_truncate(struct inode *);
0207 
0208 /* jump tables */
0209 
0210 extern const struct inode_operations     affs_file_inode_operations;
0211 extern const struct inode_operations     affs_dir_inode_operations;
0212 extern const struct inode_operations   affs_symlink_inode_operations;
0213 extern const struct file_operations  affs_file_operations;
0214 extern const struct file_operations  affs_file_operations_ofs;
0215 extern const struct file_operations  affs_dir_operations;
0216 extern const struct address_space_operations     affs_symlink_aops;
0217 extern const struct address_space_operations     affs_aops;
0218 extern const struct address_space_operations     affs_aops_ofs;
0219 
0220 extern const struct dentry_operations    affs_dentry_operations;
0221 extern const struct dentry_operations    affs_intl_dentry_operations;
0222 
0223 static inline bool affs_validblock(struct super_block *sb, int block)
0224 {
0225     return(block >= AFFS_SB(sb)->s_reserved &&
0226            block < AFFS_SB(sb)->s_partition_size);
0227 }
0228 
0229 static inline void
0230 affs_set_blocksize(struct super_block *sb, int size)
0231 {
0232     sb_set_blocksize(sb, size);
0233 }
0234 static inline struct buffer_head *
0235 affs_bread(struct super_block *sb, int block)
0236 {
0237     pr_debug("%s: %d\n", __func__, block);
0238     if (affs_validblock(sb, block))
0239         return sb_bread(sb, block);
0240     return NULL;
0241 }
0242 static inline struct buffer_head *
0243 affs_getblk(struct super_block *sb, int block)
0244 {
0245     pr_debug("%s: %d\n", __func__, block);
0246     if (affs_validblock(sb, block))
0247         return sb_getblk(sb, block);
0248     return NULL;
0249 }
0250 static inline struct buffer_head *
0251 affs_getzeroblk(struct super_block *sb, int block)
0252 {
0253     struct buffer_head *bh;
0254     pr_debug("%s: %d\n", __func__, block);
0255     if (affs_validblock(sb, block)) {
0256         bh = sb_getblk(sb, block);
0257         lock_buffer(bh);
0258         memset(bh->b_data, 0 , sb->s_blocksize);
0259         set_buffer_uptodate(bh);
0260         unlock_buffer(bh);
0261         return bh;
0262     }
0263     return NULL;
0264 }
0265 static inline struct buffer_head *
0266 affs_getemptyblk(struct super_block *sb, int block)
0267 {
0268     struct buffer_head *bh;
0269     pr_debug("%s: %d\n", __func__, block);
0270     if (affs_validblock(sb, block)) {
0271         bh = sb_getblk(sb, block);
0272         wait_on_buffer(bh);
0273         set_buffer_uptodate(bh);
0274         return bh;
0275     }
0276     return NULL;
0277 }
0278 static inline void
0279 affs_brelse(struct buffer_head *bh)
0280 {
0281     if (bh)
0282         pr_debug("%s: %lld\n", __func__, (long long) bh->b_blocknr);
0283     brelse(bh);
0284 }
0285 
0286 static inline void
0287 affs_adjust_checksum(struct buffer_head *bh, u32 val)
0288 {
0289     u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[5]);
0290     ((__be32 *)bh->b_data)[5] = cpu_to_be32(tmp - val);
0291 }
0292 static inline void
0293 affs_adjust_bitmapchecksum(struct buffer_head *bh, u32 val)
0294 {
0295     u32 tmp = be32_to_cpu(((__be32 *)bh->b_data)[0]);
0296     ((__be32 *)bh->b_data)[0] = cpu_to_be32(tmp - val);
0297 }
0298 
0299 static inline void
0300 affs_lock_link(struct inode *inode)
0301 {
0302     mutex_lock(&AFFS_I(inode)->i_link_lock);
0303 }
0304 static inline void
0305 affs_unlock_link(struct inode *inode)
0306 {
0307     mutex_unlock(&AFFS_I(inode)->i_link_lock);
0308 }
0309 static inline void
0310 affs_lock_dir(struct inode *inode)
0311 {
0312     mutex_lock_nested(&AFFS_I(inode)->i_hash_lock, SINGLE_DEPTH_NESTING);
0313 }
0314 static inline void
0315 affs_unlock_dir(struct inode *inode)
0316 {
0317     mutex_unlock(&AFFS_I(inode)->i_hash_lock);
0318 }
0319 static inline void
0320 affs_lock_ext(struct inode *inode)
0321 {
0322     mutex_lock(&AFFS_I(inode)->i_ext_lock);
0323 }
0324 static inline void
0325 affs_unlock_ext(struct inode *inode)
0326 {
0327     mutex_unlock(&AFFS_I(inode)->i_ext_lock);
0328 }