Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fs: Provide infrastructure for dynamic BDIs in filesystems

Provide helper functions for setting up dynamically allocated
backing_dev_info structures for filesystems and cleaning them up on
superblock destruction.

CC: linux-mtd@lists.infradead.org
CC: linux-nfs@vger.kernel.org
CC: Petr Vandrovec <petr@vandrovec.name>
CC: linux-nilfs@vger.kernel.org
CC: cluster-devel@redhat.com
CC: osd-dev@open-osd.org
CC: codalist@coda.cs.cmu.edu
CC: linux-afs@lists.infradead.org
CC: ecryptfs@vger.kernel.org
CC: linux-cifs@vger.kernel.org
CC: ceph-devel@vger.kernel.org
CC: linux-btrfs@vger.kernel.org
CC: v9fs-developer@lists.sourceforge.net
CC: lustre-devel@lists.lustre.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Jan Kara and committed by
Jens Axboe
fca39346 62bf42ad

+56 -1
+49
fs/super.c
··· 446 446 hlist_del_init(&sb->s_instances); 447 447 spin_unlock(&sb_lock); 448 448 up_write(&sb->s_umount); 449 + if (sb->s_iflags & SB_I_DYNBDI) { 450 + bdi_put(sb->s_bdi); 451 + sb->s_bdi = &noop_backing_dev_info; 452 + sb->s_iflags &= ~SB_I_DYNBDI; 453 + } 449 454 } 450 455 451 456 EXPORT_SYMBOL(generic_shutdown_super); ··· 1259 1254 out: 1260 1255 return ERR_PTR(error); 1261 1256 } 1257 + 1258 + /* 1259 + * Setup private BDI for given superblock. It gets automatically cleaned up 1260 + * in generic_shutdown_super(). 1261 + */ 1262 + int super_setup_bdi_name(struct super_block *sb, char *fmt, ...) 1263 + { 1264 + struct backing_dev_info *bdi; 1265 + int err; 1266 + va_list args; 1267 + 1268 + bdi = bdi_alloc(GFP_KERNEL); 1269 + if (!bdi) 1270 + return -ENOMEM; 1271 + 1272 + bdi->name = sb->s_type->name; 1273 + 1274 + va_start(args, fmt); 1275 + err = bdi_register_va(bdi, NULL, fmt, args); 1276 + va_end(args); 1277 + if (err) { 1278 + bdi_put(bdi); 1279 + return err; 1280 + } 1281 + WARN_ON(sb->s_bdi != &noop_backing_dev_info); 1282 + sb->s_bdi = bdi; 1283 + sb->s_iflags |= SB_I_DYNBDI; 1284 + 1285 + return 0; 1286 + } 1287 + EXPORT_SYMBOL(super_setup_bdi_name); 1288 + 1289 + /* 1290 + * Setup private BDI for given superblock. I gets automatically cleaned up 1291 + * in generic_shutdown_super(). 1292 + */ 1293 + int super_setup_bdi(struct super_block *sb) 1294 + { 1295 + static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); 1296 + 1297 + return super_setup_bdi_name(sb, "%.28s-%ld", sb->s_type->name, 1298 + atomic_long_inc_return(&bdi_seq)); 1299 + } 1300 + EXPORT_SYMBOL(super_setup_bdi); 1262 1301 1263 1302 /* 1264 1303 * This is an internal function, please use sb_end_{write,pagefault,intwrite}
+1 -1
include/linux/backing-dev-defs.h
··· 146 146 congested_fn *congested_fn; /* Function pointer if device is md/dm */ 147 147 void *congested_data; /* Pointer to aux data for congested func */ 148 148 149 - char *name; 149 + const char *name; 150 150 151 151 struct kref refcnt; /* Reference counter for the structure */ 152 152 unsigned int capabilities; /* Device capabilities */
+6
include/linux/fs.h
··· 1272 1272 /* sb->s_iflags to limit user namespace mounts */ 1273 1273 #define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */ 1274 1274 1275 + /* Temporary flag until all filesystems are converted to dynamic bdis */ 1276 + #define SB_I_DYNBDI 0x00000100 1277 + 1275 1278 /* Possible states of 'frozen' field */ 1276 1279 enum { 1277 1280 SB_UNFROZEN = 0, /* FS is unfrozen */ ··· 2124 2121 extern int freeze_super(struct super_block *super); 2125 2122 extern int thaw_super(struct super_block *super); 2126 2123 extern bool our_mnt(struct vfsmount *mnt); 2124 + extern __printf(2, 3) 2125 + int super_setup_bdi_name(struct super_block *sb, char *fmt, ...); 2126 + extern int super_setup_bdi(struct super_block *sb); 2127 2127 2128 2128 extern int current_umask(void); 2129 2129